| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481 |
- // Copyright (c) 2017 Valve Corporation
- // Copyright (c) 2017 LunarG Inc.
- //
- // 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 <string>
- #include <vector>
- #include "gmock/gmock.h"
- #include "test/opt/assembly_builder.h"
- #include "test/opt/pass_fixture.h"
- #include "test/opt/pass_utils.h"
- namespace spvtools {
- namespace opt {
- namespace {
- using AggressiveDCETest = PassTest<::testing::Test>;
- using ::testing::HasSubstr;
- TEST_F(AggressiveDCETest, EliminateExtendedInst) {
- // #version 140
- //
- // in vec4 BaseColor;
- // in vec4 Dead;
- //
- // void main()
- // {
- // vec4 v = BaseColor;
- // vec4 dv = sqrt(Dead);
- // gl_FragColor = v;
- // }
- const std::string spirv = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- ; CHECK: OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
- OpEntryPoint Fragment %main "main" %BaseColor %Dead %gl_FragColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- OpName %v "v"
- OpName %BaseColor "BaseColor"
- ; CHECK-NOT: OpName %dv "dv"
- OpName %dv "dv"
- ; CHECK-NOT: OpName %Dead "Dead"
- OpName %Dead "Dead"
- OpName %gl_FragColor "gl_FragColor"
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- ; CHECK-NOT: %Dead = OpVariable
- %Dead = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %gl_FragColor = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %9
- %15 = OpLabel
- %v = OpVariable %_ptr_Function_v4float Function
- ; CHECK-NOT: %dv = OpVariable
- %dv = OpVariable %_ptr_Function_v4float Function
- %16 = OpLoad %v4float %BaseColor
- OpStore %v %16
- ; CHECK-NOT: OpLoad %v4float %Dead
- %17 = OpLoad %v4float %Dead
- ; CHECK-NOT: OpExtInst %v4float %1 Sqrt
- %18 = OpExtInst %v4float %1 Sqrt %17
- ; CHECK-NOT: OpStore %dv
- OpStore %dv %18
- %19 = OpLoad %v4float %v
- OpStore %gl_FragColor %19
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateFrexp) {
- // Note: SPIR-V hand-edited to utilize Frexp
- //
- // #version 450
- //
- // in vec4 BaseColor;
- // in vec4 Dead;
- // out vec4 Color;
- // out ivec4 iv2;
- //
- // void main()
- // {
- // vec4 v = BaseColor;
- // vec4 dv = frexp(Dead, iv2);
- // Color = v;
- // }
- const std::string predefs1 =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %Dead %iv2 %Color
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- )";
- const std::string names_before =
- R"(OpName %main "main"
- OpName %v "v"
- OpName %BaseColor "BaseColor"
- OpName %dv "dv"
- OpName %Dead "Dead"
- OpName %iv2 "iv2"
- OpName %ResType "ResType"
- OpName %Color "Color"
- )";
- const std::string names_after =
- R"(OpName %main "main"
- OpName %v "v"
- OpName %BaseColor "BaseColor"
- OpName %Dead "Dead"
- OpName %iv2 "iv2"
- OpName %Color "Color"
- )";
- const std::string predefs2_before =
- R"(%void = OpTypeVoid
- %11 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %Dead = OpVariable %_ptr_Input_v4float Input
- %int = OpTypeInt 32 1
- %v4int = OpTypeVector %int 4
- %_ptr_Output_v4int = OpTypePointer Output %v4int
- %iv2 = OpVariable %_ptr_Output_v4int Output
- %ResType = OpTypeStruct %v4float %v4int
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %Color = OpVariable %_ptr_Output_v4float Output
- )";
- const std::string predefs2_after =
- R"(%void = OpTypeVoid
- %11 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %Dead = OpVariable %_ptr_Input_v4float Input
- %int = OpTypeInt 32 1
- %v4int = OpTypeVector %int 4
- %_ptr_Output_v4int = OpTypePointer Output %v4int
- %iv2 = OpVariable %_ptr_Output_v4int Output
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %Color = OpVariable %_ptr_Output_v4float Output
- )";
- const std::string func_before =
- R"(%main = OpFunction %void None %11
- %20 = OpLabel
- %v = OpVariable %_ptr_Function_v4float Function
- %dv = OpVariable %_ptr_Function_v4float Function
- %21 = OpLoad %v4float %BaseColor
- OpStore %v %21
- %22 = OpLoad %v4float %Dead
- %23 = OpExtInst %v4float %1 Frexp %22 %iv2
- OpStore %dv %23
- %24 = OpLoad %v4float %v
- OpStore %Color %24
- OpReturn
- OpFunctionEnd
- )";
- const std::string func_after =
- R"(%main = OpFunction %void None %11
- %20 = OpLabel
- %v = OpVariable %_ptr_Function_v4float Function
- %21 = OpLoad %v4float %BaseColor
- OpStore %v %21
- %22 = OpLoad %v4float %Dead
- %23 = OpExtInst %v4float %1 Frexp %22 %iv2
- %24 = OpLoad %v4float %v
- OpStore %Color %24
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(
- predefs1 + names_before + predefs2_before + func_before,
- predefs1 + names_after + predefs2_after + func_after, true, true);
- }
- TEST_F(AggressiveDCETest, EliminateDecorate) {
- // Note: The SPIR-V was hand-edited to add the OpDecorate
- //
- // #version 140
- //
- // in vec4 BaseColor;
- // in vec4 Dead;
- //
- // void main()
- // {
- // vec4 v = BaseColor;
- // vec4 dv = Dead * 0.5;
- // gl_FragColor = v;
- // }
- const std::string spirv =
- R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %Dead %gl_FragColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- OpName %v "v"
- OpName %BaseColor "BaseColor"
- OpName %dv "dv"
- OpName %Dead "Dead"
- OpName %gl_FragColor "gl_FragColor"
- ; CHECK-NOT: OpDecorate
- OpDecorate %8 RelaxedPrecision
- %void = OpTypeVoid
- %10 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %Dead = OpVariable %_ptr_Input_v4float Input
- %float_0_5 = OpConstant %float 0.5
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %gl_FragColor = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %10
- %17 = OpLabel
- %v = OpVariable %_ptr_Function_v4float Function
- %dv = OpVariable %_ptr_Function_v4float Function
- %18 = OpLoad %v4float %BaseColor
- OpStore %v %18
- %19 = OpLoad %v4float %Dead
- ; CHECK-NOT: OpVectorTimesScalar
- %8 = OpVectorTimesScalar %v4float %19 %float_0_5
- OpStore %dv %8
- %20 = OpLoad %v4float %v
- OpStore %gl_FragColor %20
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, Simple) {
- // #version 140
- //
- // in vec4 BaseColor;
- // in vec4 Dead;
- //
- // void main()
- // {
- // vec4 v = BaseColor;
- // vec4 dv = Dead;
- // gl_FragColor = v;
- // }
- const std::string spirv =
- R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- ; CHECK: OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
- OpEntryPoint Fragment %main "main" %BaseColor %Dead %gl_FragColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- OpName %v "v"
- OpName %BaseColor "BaseColor"
- ; CHECK-NOT: OpName %dv "dv"
- OpName %dv "dv"
- ; CHECK-NOT: OpName %Dead "Dead"
- OpName %Dead "Dead"
- OpName %gl_FragColor "gl_FragColor"
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- ; CHECK-NOT: %Dead = OpVariable
- %Dead = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %gl_FragColor = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %9
- %15 = OpLabel
- %v = OpVariable %_ptr_Function_v4float Function
- ; CHECK-NOT: %dv = OpVariable
- %dv = OpVariable %_ptr_Function_v4float Function
- %16 = OpLoad %v4float %BaseColor
- OpStore %v %16
- ; CHECK-NOT: OpLoad %v4float %Dead
- %17 = OpLoad %v4float %Dead
- ; CHECK-NOT: OpStore %dv
- OpStore %dv %17
- %18 = OpLoad %v4float %v
- OpStore %gl_FragColor %18
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, OptAllowListExtension) {
- // #version 140
- //
- // in vec4 BaseColor;
- // in vec4 Dead;
- //
- // void main()
- // {
- // vec4 v = BaseColor;
- // vec4 dv = Dead;
- // gl_FragColor = v;
- // }
- const std::string spirv =
- R"(OpCapability Shader
- OpExtension "SPV_AMD_gpu_shader_int16"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- ; CHECK: OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
- OpEntryPoint Fragment %main "main" %BaseColor %Dead %gl_FragColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- OpName %v "v"
- OpName %BaseColor "BaseColor"
- OpName %dv "dv"
- OpName %Dead "Dead"
- OpName %gl_FragColor "gl_FragColor"
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %Dead = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %gl_FragColor = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %9
- %15 = OpLabel
- %v = OpVariable %_ptr_Function_v4float Function
- %dv = OpVariable %_ptr_Function_v4float Function
- %16 = OpLoad %v4float %BaseColor
- OpStore %v %16
- %17 = OpLoad %v4float %Dead
- OpStore %dv %17
- %18 = OpLoad %v4float %v
- OpStore %gl_FragColor %18
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, NoOptDenyListExtension) {
- // #version 140
- //
- // in vec4 BaseColor;
- // in vec4 Dead;
- //
- // void main()
- // {
- // vec4 v = BaseColor;
- // vec4 dv = Dead;
- // gl_FragColor = v;
- // }
- const std::string assembly =
- R"(OpCapability Shader
- OpExtension "SPV_KHR_variable_pointers"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %Dead %gl_FragColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- OpName %v "v"
- OpName %BaseColor "BaseColor"
- OpName %dv "dv"
- OpName %Dead "Dead"
- OpName %gl_FragColor "gl_FragColor"
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %Dead = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %gl_FragColor = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %9
- %15 = OpLabel
- %v = OpVariable %_ptr_Function_v4float Function
- %dv = OpVariable %_ptr_Function_v4float Function
- %16 = OpLoad %v4float %BaseColor
- OpStore %v %16
- %17 = OpLoad %v4float %Dead
- OpStore %dv %17
- %18 = OpLoad %v4float %v
- OpStore %gl_FragColor %18
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, ElimWithCall) {
- // This demonstrates that "dead" function calls are not eliminated.
- // Also demonstrates that DCE will happen in presence of function call.
- // #version 140
- // in vec4 i1;
- // in vec4 i2;
- //
- // void nothing(vec4 v)
- // {
- // }
- //
- // void main()
- // {
- // vec4 v1 = i1;
- // vec4 v2 = i2;
- // nothing(v1);
- // gl_FragColor = vec4(0.0);
- // }
- const std::string text =
- R"( OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %i1 %i2 %gl_FragColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- OpName %nothing_vf4_ "nothing(vf4;"
- OpName %v "v"
- OpName %v1 "v1"
- OpName %i1 "i1"
- OpName %v2 "v2"
- OpName %i2 "i2"
- OpName %param "param"
- OpName %gl_FragColor "gl_FragColor"
- %void = OpTypeVoid
- %12 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %16 = OpTypeFunction %void %_ptr_Function_v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %i1 = OpVariable %_ptr_Input_v4float Input
- %i2 = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %gl_FragColor = OpVariable %_ptr_Output_v4float Output
- %float_0 = OpConstant %float 0
- %20 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %main = OpFunction %void None %12
- %21 = OpLabel
- %v1 = OpVariable %_ptr_Function_v4float Function
- %v2 = OpVariable %_ptr_Function_v4float Function
- %param = OpVariable %_ptr_Function_v4float Function
- %22 = OpLoad %v4float %i1
- OpStore %v1 %22
- ; CHECK-NOT: OpLoad %v4float %i2
- %23 = OpLoad %v4float %i2
- ; CHECK-NOT: OpStore %v2
- OpStore %v2 %23
- %24 = OpLoad %v4float %v1
- OpStore %param %24
- ; CHECK: OpFunctionCall %void %nothing_vf4_
- %25 = OpFunctionCall %void %nothing_vf4_ %param
- OpStore %gl_FragColor %20
- OpReturn
- OpFunctionEnd
- ; CHECK: %nothing_vf4_ = OpFunction
- %nothing_vf4_ = OpFunction %void None %16
- %v = OpFunctionParameter %_ptr_Function_v4float
- %26 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, NoParamElim) {
- // This demonstrates that unused parameters are not eliminated, but
- // dead uses of them are.
- // #version 140
- //
- // in vec4 BaseColor;
- //
- // vec4 foo(vec4 v1, vec4 v2)
- // {
- // vec4 t = -v1;
- // return v2;
- // }
- //
- // void main()
- // {
- // vec4 dead;
- // gl_FragColor = foo(dead, BaseColor);
- // }
- const std::string defs_before =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %gl_FragColor %BaseColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- OpName %foo_vf4_vf4_ "foo(vf4;vf4;"
- OpName %v1 "v1"
- OpName %v2 "v2"
- OpName %t "t"
- OpName %gl_FragColor "gl_FragColor"
- OpName %dead "dead"
- OpName %BaseColor "BaseColor"
- OpName %param "param"
- OpName %param_0 "param"
- %void = OpTypeVoid
- %13 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %17 = OpTypeFunction %v4float %_ptr_Function_v4float %_ptr_Function_v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %gl_FragColor = OpVariable %_ptr_Output_v4float Output
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %main = OpFunction %void None %13
- %20 = OpLabel
- %dead = OpVariable %_ptr_Function_v4float Function
- %param = OpVariable %_ptr_Function_v4float Function
- %param_0 = OpVariable %_ptr_Function_v4float Function
- %21 = OpLoad %v4float %dead
- OpStore %param %21
- %22 = OpLoad %v4float %BaseColor
- OpStore %param_0 %22
- %23 = OpFunctionCall %v4float %foo_vf4_vf4_ %param %param_0
- OpStore %gl_FragColor %23
- OpReturn
- OpFunctionEnd
- )";
- const std::string defs_after =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %gl_FragColor %BaseColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- OpName %foo_vf4_vf4_ "foo(vf4;vf4;"
- OpName %v1 "v1"
- OpName %v2 "v2"
- OpName %gl_FragColor "gl_FragColor"
- OpName %dead "dead"
- OpName %BaseColor "BaseColor"
- OpName %param "param"
- OpName %param_0 "param"
- %void = OpTypeVoid
- %13 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %17 = OpTypeFunction %v4float %_ptr_Function_v4float %_ptr_Function_v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %gl_FragColor = OpVariable %_ptr_Output_v4float Output
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %main = OpFunction %void None %13
- %20 = OpLabel
- %dead = OpVariable %_ptr_Function_v4float Function
- %param = OpVariable %_ptr_Function_v4float Function
- %param_0 = OpVariable %_ptr_Function_v4float Function
- %21 = OpLoad %v4float %dead
- OpStore %param %21
- %22 = OpLoad %v4float %BaseColor
- OpStore %param_0 %22
- %23 = OpFunctionCall %v4float %foo_vf4_vf4_ %param %param_0
- OpStore %gl_FragColor %23
- OpReturn
- OpFunctionEnd
- )";
- const std::string func_before =
- R"(%foo_vf4_vf4_ = OpFunction %v4float None %17
- %v1 = OpFunctionParameter %_ptr_Function_v4float
- %v2 = OpFunctionParameter %_ptr_Function_v4float
- %24 = OpLabel
- %t = OpVariable %_ptr_Function_v4float Function
- %25 = OpLoad %v4float %v1
- %26 = OpFNegate %v4float %25
- OpStore %t %26
- %27 = OpLoad %v4float %v2
- OpReturnValue %27
- OpFunctionEnd
- )";
- const std::string func_after =
- R"(%foo_vf4_vf4_ = OpFunction %v4float None %17
- %v1 = OpFunctionParameter %_ptr_Function_v4float
- %v2 = OpFunctionParameter %_ptr_Function_v4float
- %24 = OpLabel
- %27 = OpLoad %v4float %v2
- OpReturnValue %27
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(defs_before + func_before,
- defs_after + func_after, true, true);
- }
- TEST_F(AggressiveDCETest, ElimOpaque) {
- // SPIR-V not representable from GLSL; not generatable from HLSL
- // for the moment.
- const std::string defs_before =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %outColor %texCoords
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- OpName %S_t "S_t"
- OpMemberName %S_t 0 "v0"
- OpMemberName %S_t 1 "v1"
- OpMemberName %S_t 2 "smp"
- OpName %outColor "outColor"
- OpName %sampler15 "sampler15"
- OpName %s0 "s0"
- OpName %texCoords "texCoords"
- OpDecorate %sampler15 DescriptorSet 0
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %outColor = OpVariable %_ptr_Output_v4float Output
- %14 = OpTypeImage %float 2D 0 0 0 1 Unknown
- %15 = OpTypeSampledImage %14
- %S_t = OpTypeStruct %v2float %v2float %15
- %_ptr_Function_S_t = OpTypePointer Function %S_t
- %17 = OpTypeFunction %void %_ptr_Function_S_t
- %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
- %_ptr_Function_15 = OpTypePointer Function %15
- %sampler15 = OpVariable %_ptr_UniformConstant_15 UniformConstant
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %_ptr_Function_v2float = OpTypePointer Function %v2float
- %_ptr_Input_v2float = OpTypePointer Input %v2float
- %texCoords = OpVariable %_ptr_Input_v2float Input
- )";
- const std::string defs_after =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %outColor %texCoords
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- OpName %outColor "outColor"
- OpName %sampler15 "sampler15"
- OpName %texCoords "texCoords"
- OpDecorate %sampler15 DescriptorSet 0
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %outColor = OpVariable %_ptr_Output_v4float Output
- %14 = OpTypeImage %float 2D 0 0 0 1 Unknown
- %15 = OpTypeSampledImage %14
- %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
- %sampler15 = OpVariable %_ptr_UniformConstant_15 UniformConstant
- %_ptr_Input_v2float = OpTypePointer Input %v2float
- %texCoords = OpVariable %_ptr_Input_v2float Input
- )";
- const std::string func_before =
- R"(%main = OpFunction %void None %9
- %25 = OpLabel
- %s0 = OpVariable %_ptr_Function_S_t Function
- %26 = OpLoad %v2float %texCoords
- %27 = OpLoad %S_t %s0
- %28 = OpCompositeInsert %S_t %26 %27 0
- %29 = OpLoad %15 %sampler15
- %30 = OpCompositeInsert %S_t %29 %28 2
- OpStore %s0 %30
- %31 = OpImageSampleImplicitLod %v4float %29 %26
- OpStore %outColor %31
- OpReturn
- OpFunctionEnd
- )";
- const std::string func_after =
- R"(%main = OpFunction %void None %9
- %25 = OpLabel
- %26 = OpLoad %v2float %texCoords
- %29 = OpLoad %15 %sampler15
- %31 = OpImageSampleImplicitLod %v4float %29 %26
- OpStore %outColor %31
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(defs_before + func_before,
- defs_after + func_after, true, true);
- }
- TEST_F(AggressiveDCETest, NoParamStoreElim) {
- // Should not eliminate stores to params
- //
- // #version 450
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 0) out vec4 OutColor;
- //
- // void foo(in vec4 v1, out vec4 v2)
- // {
- // v2 = -v1;
- // }
- //
- // void main()
- // {
- // foo(BaseColor, OutColor);
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %foo_vf4_vf4_ "foo(vf4;vf4;"
- OpName %v1 "v1"
- OpName %v2 "v2"
- OpName %BaseColor "BaseColor"
- OpName %OutColor "OutColor"
- OpName %param "param"
- OpName %param_0 "param"
- OpDecorate %BaseColor Location 0
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %11 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %15 = OpTypeFunction %void %_ptr_Function_v4float %_ptr_Function_v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %11
- %18 = OpLabel
- %param = OpVariable %_ptr_Function_v4float Function
- %param_0 = OpVariable %_ptr_Function_v4float Function
- %19 = OpLoad %v4float %BaseColor
- OpStore %param %19
- %20 = OpFunctionCall %void %foo_vf4_vf4_ %param %param_0
- %21 = OpLoad %v4float %param_0
- OpStore %OutColor %21
- OpReturn
- OpFunctionEnd
- %foo_vf4_vf4_ = OpFunction %void None %15
- %v1 = OpFunctionParameter %_ptr_Function_v4float
- %v2 = OpFunctionParameter %_ptr_Function_v4float
- %22 = OpLabel
- %23 = OpLoad %v4float %v1
- %24 = OpFNegate %v4float %23
- OpStore %v2 %24
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, PrivateStoreElimInEntryNoCalls) {
- // Eliminate stores to private in entry point with no calls
- // Note: Not legal GLSL
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 1) in vec4 Dead;
- // layout(location = 0) out vec4 OutColor;
- //
- // private vec4 dv;
- //
- // void main()
- // {
- // vec4 v = BaseColor;
- // dv = Dead;
- // OutColor = v;
- // }
- const std::string spirv =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %Dead %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %v "v"
- OpName %BaseColor "BaseColor"
- ; CHECK-NOT: OpName %dv "dv"
- OpName %dv "dv"
- OpName %Dead "Dead"
- OpName %OutColor "OutColor"
- OpDecorate %BaseColor Location 0
- OpDecorate %Dead Location 1
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- ; CHECK-NOT: OpTypePointer Private
- %_ptr_Private_v4float = OpTypePointer Private %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %Dead = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- ; CHECK-NOT: %dv = OpVariable
- %dv = OpVariable %_ptr_Private_v4float Private
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %9
- %16 = OpLabel
- %v = OpVariable %_ptr_Function_v4float Function
- %17 = OpLoad %v4float %BaseColor
- OpStore %v %17
- %18 = OpLoad %v4float %Dead
- ; CHECK-NOT: OpStore %dv
- OpStore %dv %18
- %19 = OpLoad %v4float %v
- %20 = OpFNegate %v4float %19
- OpStore %OutColor %20
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, NoPrivateStoreElimIfLoad) {
- // Should not eliminate stores to private when there is a load
- // Note: Not legal GLSL
- //
- // #version 450
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 0) out vec4 OutColor;
- //
- // private vec4 pv;
- //
- // void main()
- // {
- // pv = BaseColor;
- // OutColor = pv;
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %pv "pv"
- OpName %BaseColor "BaseColor"
- OpName %OutColor "OutColor"
- OpDecorate %BaseColor Location 0
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Private_v4float = OpTypePointer Private %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %pv = OpVariable %_ptr_Private_v4float Private
- %main = OpFunction %void None %7
- %13 = OpLabel
- %14 = OpLoad %v4float %BaseColor
- OpStore %pv %14
- %15 = OpLoad %v4float %pv
- %16 = OpFNegate %v4float %15
- OpStore %OutColor %16
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, NoPrivateStoreElimWithCall) {
- // Should not eliminate stores to private when function contains call
- // Note: Not legal GLSL
- //
- // #version 450
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 0) out vec4 OutColor;
- //
- // private vec4 v1;
- //
- // void foo()
- // {
- // OutColor = -v1;
- // }
- //
- // void main()
- // {
- // v1 = BaseColor;
- // foo();
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %OutColor %BaseColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %foo_ "foo("
- OpName %OutColor "OutColor"
- OpName %v1 "v1"
- OpName %BaseColor "BaseColor"
- OpDecorate %OutColor Location 0
- OpDecorate %BaseColor Location 0
- %void = OpTypeVoid
- %8 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %_ptr_Private_v4float = OpTypePointer Private %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %v1 = OpVariable %_ptr_Private_v4float Private
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %main = OpFunction %void None %8
- %14 = OpLabel
- %15 = OpLoad %v4float %BaseColor
- OpStore %v1 %15
- %16 = OpFunctionCall %void %foo_
- OpReturn
- OpFunctionEnd
- %foo_ = OpFunction %void None %8
- %17 = OpLabel
- %18 = OpLoad %v4float %v1
- %19 = OpFNegate %v4float %18
- OpStore %OutColor %19
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, NoPrivateStoreElimInNonEntry) {
- // Should not eliminate stores to private when function is not entry point
- // Note: Not legal GLSL
- //
- // #version 450
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 0) out vec4 OutColor;
- //
- // private vec4 v1;
- //
- // void foo()
- // {
- // v1 = BaseColor;
- // }
- //
- // void main()
- // {
- // foo();
- // OutColor = -v1;
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %foo_ "foo("
- OpName %v1 "v1"
- OpName %BaseColor "BaseColor"
- OpName %OutColor "OutColor"
- OpDecorate %BaseColor Location 0
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %8 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Private_v4float = OpTypePointer Private %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %v1 = OpVariable %_ptr_Private_v4float Private
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %8
- %14 = OpLabel
- %15 = OpFunctionCall %void %foo_
- %16 = OpLoad %v4float %v1
- %17 = OpFNegate %v4float %16
- OpStore %OutColor %17
- OpReturn
- OpFunctionEnd
- %foo_ = OpFunction %void None %8
- %18 = OpLabel
- %19 = OpLoad %v4float %BaseColor
- OpStore %v1 %19
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, WorkgroupStoreElimInEntryNoCalls) {
- // Eliminate stores to private in entry point with no calls
- // Note: Not legal GLSL
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 1) in vec4 Dead;
- // layout(location = 0) out vec4 OutColor;
- //
- // workgroup vec4 dv;
- //
- // void main()
- // {
- // vec4 v = BaseColor;
- // dv = Dead;
- // OutColor = v;
- // }
- const std::string spirv =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %Dead %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %v "v"
- OpName %BaseColor "BaseColor"
- ; CHECK-NOT: OpName %dv "dv"
- OpName %dv "dv"
- OpName %Dead "Dead"
- OpName %OutColor "OutColor"
- OpDecorate %BaseColor Location 0
- OpDecorate %Dead Location 1
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- ; CHECK-NOT: OpTypePointer Workgroup
- %_ptr_Workgroup_v4float = OpTypePointer Workgroup %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %Dead = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- ; CHECK-NOT: %dv = OpVariable
- %dv = OpVariable %_ptr_Workgroup_v4float Workgroup
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %9
- %16 = OpLabel
- %v = OpVariable %_ptr_Function_v4float Function
- %17 = OpLoad %v4float %BaseColor
- OpStore %v %17
- %18 = OpLoad %v4float %Dead
- ; CHECK-NOT: OpStore %dv
- OpStore %dv %18
- %19 = OpLoad %v4float %v
- %20 = OpFNegate %v4float %19
- OpStore %OutColor %20
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, EliminateDeadIfThenElse) {
- // #version 450
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 0) out vec4 OutColor;
- //
- // void main()
- // {
- // float d;
- // if (BaseColor.x == 0)
- // d = BaseColor.y;
- // else
- // d = BaseColor.z;
- // OutColor = vec4(1.0,1.0,1.0,1.0);
- // }
- const std::string spirv =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %BaseColor "BaseColor"
- OpName %d "d"
- OpName %OutColor "OutColor"
- OpDecorate %BaseColor Location 0
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %_ptr_Input_float = OpTypePointer Input %float
- %float_0 = OpConstant %float 0
- %bool = OpTypeBool
- %_ptr_Function_float = OpTypePointer Function %float
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %float_1 = OpConstant %float 1
- %21 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
- ; CHECK: = OpFunction %void
- ; CHECK-NEXT: %22 = OpLabel
- ; CHECK-NEXT: OpBranch %26
- ; CHECK-NEXT: %26 = OpLabel
- %main = OpFunction %void None %7
- %22 = OpLabel
- %d = OpVariable %_ptr_Function_float Function
- %23 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
- %24 = OpLoad %float %23
- %25 = OpFOrdEqual %bool %24 %float_0
- OpSelectionMerge %26 None
- OpBranchConditional %25 %27 %28
- %27 = OpLabel
- %29 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
- %30 = OpLoad %float %29
- OpStore %d %30
- OpBranch %26
- %28 = OpLabel
- %31 = OpAccessChain %_ptr_Input_float %BaseColor %uint_2
- %32 = OpLoad %float %31
- OpStore %d %32
- OpBranch %26
- %26 = OpLabel
- OpStore %OutColor %21
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, EliminateDeadIfThen) {
- // #version 450
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 0) out vec4 OutColor;
- //
- // void main()
- // {
- // float d;
- // if (BaseColor.x == 0)
- // d = BaseColor.y;
- // OutColor = vec4(1.0,1.0,1.0,1.0);
- // }
- const std::string spirv =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %BaseColor "BaseColor"
- OpName %d "d"
- OpName %OutColor "OutColor"
- OpDecorate %BaseColor Location 0
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %_ptr_Input_float = OpTypePointer Input %float
- %float_0 = OpConstant %float 0
- %bool = OpTypeBool
- %_ptr_Function_float = OpTypePointer Function %float
- %uint_1 = OpConstant %uint 1
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %float_1 = OpConstant %float 1
- %20 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
- ; CHECK: = OpFunction
- ; CHECK-NEXT: %21 = OpLabel
- ; CHECK-NEXT: OpBranch [[target:%\w+]]
- ; CHECK-NEXT: [[target]] = OpLabel
- %main = OpFunction %void None %7
- %21 = OpLabel
- %d = OpVariable %_ptr_Function_float Function
- %22 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
- %23 = OpLoad %float %22
- %24 = OpFOrdEqual %bool %23 %float_0
- OpSelectionMerge %25 None
- OpBranchConditional %24 %26 %25
- %26 = OpLabel
- %27 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
- %28 = OpLoad %float %27
- OpStore %d %28
- OpBranch %25
- %25 = OpLabel
- OpStore %OutColor %20
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, EliminateDeadSwitch) {
- // #version 450
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 1) in flat int x;
- // layout(location = 0) out vec4 OutColor;
- //
- // void main()
- // {
- // float d;
- // switch (x) {
- // case 0:
- // d = BaseColor.y;
- // }
- // OutColor = vec4(1.0,1.0,1.0,1.0);
- // }
- const std::string spirv =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %x %BaseColor %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %x "x"
- OpName %d "d"
- OpName %BaseColor "BaseColor"
- OpName %OutColor "OutColor"
- OpDecorate %x Flat
- OpDecorate %x Location 1
- OpDecorate %BaseColor Location 0
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_Input_int = OpTypePointer Input %int
- %x = OpVariable %_ptr_Input_int Input
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %uint = OpTypeInt 32 0
- %uint_1 = OpConstant %uint 1
- %_ptr_Input_float = OpTypePointer Input %float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %float_1 = OpConstant %float 1
- %27 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
- ; CHECK: = OpFunction
- ; CHECK-NEXT: = OpLabel
- ; CHECK-NEXT: OpBranch [[target:%\w+]]
- ; CHECK-NEXT: [[target]] = OpLabel
- %main = OpFunction %void None %3
- %5 = OpLabel
- %d = OpVariable %_ptr_Function_float Function
- %9 = OpLoad %int %x
- OpSelectionMerge %11 None
- OpSwitch %9 %11 0 %10
- %10 = OpLabel
- %21 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
- %22 = OpLoad %float %21
- OpStore %d %22
- OpBranch %11
- %11 = OpLabel
- OpStore %OutColor %27
- OpReturn
- OpFunctionEnd)";
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, EliminateDeadIfThenElseNested) {
- // #version 450
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 0) out vec4 OutColor;
- //
- // void main()
- // {
- // float d;
- // if (BaseColor.x == 0)
- // if (BaseColor.y == 0)
- // d = 0.0;
- // else
- // d = 0.25;
- // else
- // if (BaseColor.y == 0)
- // d = 0.5;
- // else
- // d = 0.75;
- // OutColor = vec4(1.0,1.0,1.0,1.0);
- // }
- const std::string spirv =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %BaseColor "BaseColor"
- OpName %d "d"
- OpName %OutColor "OutColor"
- OpDecorate %BaseColor Location 0
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %_ptr_Input_float = OpTypePointer Input %float
- %float_0 = OpConstant %float 0
- %bool = OpTypeBool
- %uint_1 = OpConstant %uint 1
- %_ptr_Function_float = OpTypePointer Function %float
- %float_0_25 = OpConstant %float 0.25
- %float_0_5 = OpConstant %float 0.5
- %float_0_75 = OpConstant %float 0.75
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %float_1 = OpConstant %float 1
- %23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
- ; CHECK: = OpFunction
- ; CHECK-NEXT: = OpLabel
- ; CHECK-NEXT: OpBranch [[target:%\w+]]
- ; CHECK-NEXT: [[target]] = OpLabel
- ; CHECK-NOT: OpLabel
- %main = OpFunction %void None %7
- %24 = OpLabel
- %d = OpVariable %_ptr_Function_float Function
- %25 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
- %26 = OpLoad %float %25
- %27 = OpFOrdEqual %bool %26 %float_0
- OpSelectionMerge %28 None
- OpBranchConditional %27 %29 %30
- %29 = OpLabel
- %31 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
- %32 = OpLoad %float %31
- %33 = OpFOrdEqual %bool %32 %float_0
- OpSelectionMerge %34 None
- OpBranchConditional %33 %35 %36
- %35 = OpLabel
- OpStore %d %float_0
- OpBranch %34
- %36 = OpLabel
- OpStore %d %float_0_25
- OpBranch %34
- %34 = OpLabel
- OpBranch %28
- %30 = OpLabel
- %37 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
- %38 = OpLoad %float %37
- %39 = OpFOrdEqual %bool %38 %float_0
- OpSelectionMerge %40 None
- OpBranchConditional %39 %41 %42
- %41 = OpLabel
- OpStore %d %float_0_5
- OpBranch %40
- %42 = OpLabel
- OpStore %d %float_0_75
- OpBranch %40
- %40 = OpLabel
- OpBranch %28
- %28 = OpLabel
- OpStore %OutColor %23
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateLiveIfThenElse) {
- // #version 450
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 0) out vec4 OutColor;
- //
- // void main()
- // {
- // float t;
- // if (BaseColor.x == 0)
- // t = BaseColor.y;
- // else
- // t = BaseColor.z;
- // OutColor = vec4(t);
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %BaseColor "BaseColor"
- OpName %t "t"
- OpName %OutColor "OutColor"
- OpDecorate %BaseColor Location 0
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %_ptr_Input_float = OpTypePointer Input %float
- %float_0 = OpConstant %float 0
- %bool = OpTypeBool
- %_ptr_Function_float = OpTypePointer Function %float
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %7
- %20 = OpLabel
- %t = OpVariable %_ptr_Function_float Function
- %21 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
- %22 = OpLoad %float %21
- %23 = OpFOrdEqual %bool %22 %float_0
- OpSelectionMerge %24 None
- OpBranchConditional %23 %25 %26
- %25 = OpLabel
- %27 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
- %28 = OpLoad %float %27
- OpStore %t %28
- OpBranch %24
- %26 = OpLabel
- %29 = OpAccessChain %_ptr_Input_float %BaseColor %uint_2
- %30 = OpLoad %float %29
- OpStore %t %30
- OpBranch %24
- %24 = OpLabel
- %31 = OpLoad %float %t
- %32 = OpCompositeConstruct %v4float %31 %31 %31 %31
- OpStore %OutColor %32
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateLiveIfThenElseNested) {
- // #version 450
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 0) out vec4 OutColor;
- //
- // void main()
- // {
- // float t;
- // if (BaseColor.x == 0)
- // if (BaseColor.y == 0)
- // t = 0.0;
- // else
- // t = 0.25;
- // else
- // if (BaseColor.y == 0)
- // t = 0.5;
- // else
- // t = 0.75;
- // OutColor = vec4(t);
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %BaseColor "BaseColor"
- OpName %t "t"
- OpName %OutColor "OutColor"
- OpDecorate %BaseColor Location 0
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %_ptr_Input_float = OpTypePointer Input %float
- %float_0 = OpConstant %float 0
- %bool = OpTypeBool
- %uint_1 = OpConstant %uint 1
- %_ptr_Function_float = OpTypePointer Function %float
- %float_0_25 = OpConstant %float 0.25
- %float_0_5 = OpConstant %float 0.5
- %float_0_75 = OpConstant %float 0.75
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %7
- %22 = OpLabel
- %t = OpVariable %_ptr_Function_float Function
- %23 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
- %24 = OpLoad %float %23
- %25 = OpFOrdEqual %bool %24 %float_0
- OpSelectionMerge %26 None
- OpBranchConditional %25 %27 %28
- %27 = OpLabel
- %29 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
- %30 = OpLoad %float %29
- %31 = OpFOrdEqual %bool %30 %float_0
- OpSelectionMerge %32 None
- OpBranchConditional %31 %33 %34
- %33 = OpLabel
- OpStore %t %float_0
- OpBranch %32
- %34 = OpLabel
- OpStore %t %float_0_25
- OpBranch %32
- %32 = OpLabel
- OpBranch %26
- %28 = OpLabel
- %35 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
- %36 = OpLoad %float %35
- %37 = OpFOrdEqual %bool %36 %float_0
- OpSelectionMerge %38 None
- OpBranchConditional %37 %39 %40
- %39 = OpLabel
- OpStore %t %float_0_5
- OpBranch %38
- %40 = OpLabel
- OpStore %t %float_0_75
- OpBranch %38
- %38 = OpLabel
- OpBranch %26
- %26 = OpLabel
- %41 = OpLoad %float %t
- %42 = OpCompositeConstruct %v4float %41 %41 %41 %41
- OpStore %OutColor %42
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateIfWithPhi) {
- // Note: Assembly hand-optimized from GLSL
- //
- // #version 450
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 0) out vec4 OutColor;
- //
- // void main()
- // {
- // float t;
- // if (BaseColor.x == 0)
- // t = 0.0;
- // else
- // t = 1.0;
- // OutColor = vec4(t);
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %BaseColor "BaseColor"
- OpName %OutColor "OutColor"
- OpDecorate %BaseColor Location 0
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %6 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %_ptr_Input_float = OpTypePointer Input %float
- %float_0 = OpConstant %float 0
- %bool = OpTypeBool
- %float_1 = OpConstant %float 1
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %6
- %17 = OpLabel
- %18 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
- %19 = OpLoad %float %18
- %20 = OpFOrdEqual %bool %19 %float_0
- OpSelectionMerge %21 None
- OpBranchConditional %20 %22 %23
- %22 = OpLabel
- OpBranch %21
- %23 = OpLabel
- OpBranch %21
- %21 = OpLabel
- %24 = OpPhi %float %float_0 %22 %float_1 %23
- %25 = OpCompositeConstruct %v4float %24 %24 %24 %24
- OpStore %OutColor %25
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateIfBreak) {
- // Note: Assembly optimized from GLSL
- //
- // #version 450
- //
- // layout(location=0) in vec4 InColor;
- // layout(location=0) out vec4 OutColor;
- //
- // void main()
- // {
- // float f = 0.0;
- // for (;;) {
- // f += 2.0;
- // if (f > 20.0)
- // break;
- // }
- //
- // OutColor = InColor / f;
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %OutColor %InColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %f "f"
- OpName %OutColor "OutColor"
- OpName %InColor "InColor"
- OpDecorate %OutColor Location 0
- OpDecorate %InColor Location 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %float_0 = OpConstant %float 0
- %float_2 = OpConstant %float 2
- %float_20 = OpConstant %float 20
- %bool = OpTypeBool
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %OutColor = OpVariable %_ptr_Output_v4float Output
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %InColor = OpVariable %_ptr_Input_v4float Input
- %main = OpFunction %void None %7
- %17 = OpLabel
- %f = OpVariable %_ptr_Function_float Function
- OpStore %f %float_0
- OpBranch %18
- %18 = OpLabel
- OpLoopMerge %19 %20 None
- OpBranch %21
- %21 = OpLabel
- %22 = OpLoad %float %f
- %23 = OpFAdd %float %22 %float_2
- OpStore %f %23
- %24 = OpLoad %float %f
- %25 = OpFOrdGreaterThan %bool %24 %float_20
- OpSelectionMerge %26 None
- OpBranchConditional %25 %27 %26
- %27 = OpLabel
- OpBranch %19
- %26 = OpLabel
- OpBranch %20
- %20 = OpLabel
- OpBranch %18
- %19 = OpLabel
- %28 = OpLoad %v4float %InColor
- %29 = OpLoad %float %f
- %30 = OpCompositeConstruct %v4float %29 %29 %29 %29
- %31 = OpFDiv %v4float %28 %30
- OpStore %OutColor %31
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateIfBreak2) {
- // Do not eliminate break as conditional branch with merge instruction
- // Note: SPIR-V edited to add merge instruction before break.
- //
- // #version 430
- //
- // layout(std430) buffer U_t
- // {
- // float g_F[10];
- // };
- //
- // layout(location = 0)out float o;
- //
- // void main(void)
- // {
- // float s = 0.0;
- // for (int i=0; i<10; i++)
- // s += g_F[i];
- // o = s;
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %s "s"
- OpName %i "i"
- OpName %U_t "U_t"
- OpMemberName %U_t 0 "g_F"
- OpName %_ ""
- OpName %o "o"
- OpDecorate %_arr_float_uint_10 ArrayStride 4
- OpMemberDecorate %U_t 0 Offset 0
- OpDecorate %U_t BufferBlock
- OpDecorate %_ DescriptorSet 0
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %10 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %int_0 = OpConstant %int 0
- %int_10 = OpConstant %int 10
- %bool = OpTypeBool
- %uint = OpTypeInt 32 0
- %uint_10 = OpConstant %uint 10
- %_arr_float_uint_10 = OpTypeArray %float %uint_10
- %U_t = OpTypeStruct %_arr_float_uint_10
- %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
- %_ = OpVariable %_ptr_Uniform_U_t Uniform
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %int_1 = OpConstant %int 1
- %_ptr_Output_float = OpTypePointer Output %float
- %o = OpVariable %_ptr_Output_float Output
- %main = OpFunction %void None %10
- %25 = OpLabel
- %s = OpVariable %_ptr_Function_float Function
- %i = OpVariable %_ptr_Function_int Function
- OpStore %s %float_0
- OpStore %i %int_0
- OpBranch %26
- %26 = OpLabel
- OpLoopMerge %27 %28 None
- OpBranch %29
- %29 = OpLabel
- %30 = OpLoad %int %i
- %31 = OpSLessThan %bool %30 %int_10
- OpSelectionMerge %32 None
- OpBranchConditional %31 %32 %27
- %32 = OpLabel
- %33 = OpLoad %int %i
- %34 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %33
- %35 = OpLoad %float %34
- %36 = OpLoad %float %s
- %37 = OpFAdd %float %36 %35
- OpStore %s %37
- OpBranch %28
- %28 = OpLabel
- %38 = OpLoad %int %i
- %39 = OpIAdd %int %38 %int_1
- OpStore %i %39
- OpBranch %26
- %27 = OpLabel
- %40 = OpLoad %float %s
- OpStore %o %40
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, EliminateEntireUselessLoop) {
- // #version 140
- // in vec4 BaseColor;
- //
- // layout(std140) uniform U_t
- // {
- // int g_I ;
- // } ;
- //
- // void main()
- // {
- // vec4 v = BaseColor;
- // float df = 0.0;
- // int i = 0;
- // while (i < g_I) {
- // df = df * 0.5;
- // i = i + 1;
- // }
- // gl_FragColor = v;
- // }
- const std::string predefs1 =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- )";
- const std::string names_before =
- R"(OpName %main "main"
- OpName %v "v"
- OpName %BaseColor "BaseColor"
- OpName %df "df"
- OpName %i "i"
- OpName %U_t "U_t"
- OpMemberName %U_t 0 "g_I"
- OpName %_ ""
- OpName %gl_FragColor "gl_FragColor"
- )";
- const std::string names_after =
- R"(OpName %main "main"
- OpName %v "v"
- OpName %BaseColor "BaseColor"
- OpName %gl_FragColor "gl_FragColor"
- )";
- const std::string predefs2_before =
- R"(OpMemberDecorate %U_t 0 Offset 0
- OpDecorate %U_t Block
- OpDecorate %_ DescriptorSet 0
- %void = OpTypeVoid
- %11 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %_ptr_Function_float = OpTypePointer Function %float
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %int_0 = OpConstant %int 0
- %U_t = OpTypeStruct %int
- %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
- %_ = OpVariable %_ptr_Uniform_U_t Uniform
- %_ptr_Uniform_int = OpTypePointer Uniform %int
- %bool = OpTypeBool
- %float_0_5 = OpConstant %float 0.5
- %int_1 = OpConstant %int 1
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %gl_FragColor = OpVariable %_ptr_Output_v4float Output
- )";
- const std::string predefs2_after =
- R"(%void = OpTypeVoid
- %11 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %gl_FragColor = OpVariable %_ptr_Output_v4float Output
- )";
- const std::string func_before =
- R"(%main = OpFunction %void None %11
- %27 = OpLabel
- %v = OpVariable %_ptr_Function_v4float Function
- %df = OpVariable %_ptr_Function_float Function
- %i = OpVariable %_ptr_Function_int Function
- %28 = OpLoad %v4float %BaseColor
- OpStore %v %28
- OpStore %df %float_0
- OpStore %i %int_0
- OpBranch %29
- %29 = OpLabel
- OpLoopMerge %30 %31 None
- OpBranch %32
- %32 = OpLabel
- %33 = OpLoad %int %i
- %34 = OpAccessChain %_ptr_Uniform_int %_ %int_0
- %35 = OpLoad %int %34
- %36 = OpSLessThan %bool %33 %35
- OpBranchConditional %36 %37 %30
- %37 = OpLabel
- %38 = OpLoad %float %df
- %39 = OpFMul %float %38 %float_0_5
- OpStore %df %39
- %40 = OpLoad %int %i
- %41 = OpIAdd %int %40 %int_1
- OpStore %i %41
- OpBranch %31
- %31 = OpLabel
- OpBranch %29
- %30 = OpLabel
- %42 = OpLoad %v4float %v
- OpStore %gl_FragColor %42
- OpReturn
- OpFunctionEnd
- )";
- const std::string func_after =
- R"(%main = OpFunction %void None %11
- %27 = OpLabel
- %v = OpVariable %_ptr_Function_v4float Function
- %28 = OpLoad %v4float %BaseColor
- OpStore %v %28
- OpBranch %29
- %29 = OpLabel
- OpBranch %30
- %30 = OpLabel
- %42 = OpLoad %v4float %v
- OpStore %gl_FragColor %42
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(
- predefs1 + names_before + predefs2_before + func_before,
- predefs1 + names_after + predefs2_after + func_after, true, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateBusyLoop) {
- // Note: SPIR-V edited to replace AtomicAdd(i,0) with AtomicLoad(i)
- //
- // #version 450
- //
- // layout(std430) buffer I_t
- // {
- // int g_I;
- // int g_I2;
- // };
- //
- // layout(location = 0) out int o;
- //
- // void main(void)
- // {
- // while (atomicAdd(g_I, 0) == 0) {}
- // o = g_I2;
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %I_t "I_t"
- OpMemberName %I_t 0 "g_I"
- OpMemberName %I_t 1 "g_I2"
- OpName %_ ""
- OpName %o "o"
- OpMemberDecorate %I_t 0 Offset 0
- OpMemberDecorate %I_t 1 Offset 4
- OpDecorate %I_t BufferBlock
- OpDecorate %_ DescriptorSet 0
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %I_t = OpTypeStruct %int %int
- %_ptr_Uniform_I_t = OpTypePointer Uniform %I_t
- %_ = OpVariable %_ptr_Uniform_I_t Uniform
- %int_0 = OpConstant %int 0
- %int_1 = OpConstant %int 1
- %_ptr_Uniform_int = OpTypePointer Uniform %int
- %uint = OpTypeInt 32 0
- %uint_1 = OpConstant %uint 1
- %uint_0 = OpConstant %uint 0
- %bool = OpTypeBool
- %_ptr_Output_int = OpTypePointer Output %int
- %o = OpVariable %_ptr_Output_int Output
- %main = OpFunction %void None %7
- %18 = OpLabel
- OpBranch %19
- %19 = OpLabel
- OpLoopMerge %20 %21 None
- OpBranch %22
- %22 = OpLabel
- %23 = OpAccessChain %_ptr_Uniform_int %_ %int_0
- %24 = OpAtomicLoad %int %23 %uint_1 %uint_0
- %25 = OpIEqual %bool %24 %int_0
- OpBranchConditional %25 %26 %20
- %26 = OpLabel
- OpBranch %21
- %21 = OpLabel
- OpBranch %19
- %20 = OpLabel
- %27 = OpAccessChain %_ptr_Uniform_int %_ %int_1
- %28 = OpLoad %int %27
- OpStore %o %28
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateLiveLoop) {
- // Note: SPIR-V optimized
- //
- // #version 430
- //
- // layout(std430) buffer U_t
- // {
- // float g_F[10];
- // };
- //
- // layout(location = 0)out float o;
- //
- // void main(void)
- // {
- // float s = 0.0;
- // for (int i=0; i<10; i++)
- // s += g_F[i];
- // o = s;
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %U_t "U_t"
- OpMemberName %U_t 0 "g_F"
- OpName %_ ""
- OpName %o "o"
- OpDecorate %_arr_float_uint_10 ArrayStride 4
- OpMemberDecorate %U_t 0 Offset 0
- OpDecorate %U_t BufferBlock
- OpDecorate %_ DescriptorSet 0
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %8 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %int_10 = OpConstant %int 10
- %bool = OpTypeBool
- %uint = OpTypeInt 32 0
- %uint_10 = OpConstant %uint 10
- %_arr_float_uint_10 = OpTypeArray %float %uint_10
- %U_t = OpTypeStruct %_arr_float_uint_10
- %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
- %_ = OpVariable %_ptr_Uniform_U_t Uniform
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %int_1 = OpConstant %int 1
- %_ptr_Output_float = OpTypePointer Output %float
- %o = OpVariable %_ptr_Output_float Output
- %main = OpFunction %void None %8
- %21 = OpLabel
- OpBranch %22
- %22 = OpLabel
- %23 = OpPhi %float %float_0 %21 %24 %25
- %26 = OpPhi %int %int_0 %21 %27 %25
- OpLoopMerge %28 %25 None
- OpBranch %29
- %29 = OpLabel
- %30 = OpSLessThan %bool %26 %int_10
- OpBranchConditional %30 %31 %28
- %31 = OpLabel
- %32 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %26
- %33 = OpLoad %float %32
- %24 = OpFAdd %float %23 %33
- OpBranch %25
- %25 = OpLabel
- %27 = OpIAdd %int %26 %int_1
- OpBranch %22
- %28 = OpLabel
- OpStore %o %23
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, EliminateEntireFunctionBody) {
- // #version 450
- //
- // layout(location = 0) in vec4 BaseColor;
- // layout(location = 0) out vec4 OutColor;
- //
- // void main()
- // {
- // float d;
- // if (BaseColor.x == 0)
- // d = BaseColor.y;
- // else
- // d = BaseColor.z;
- // }
- const std::string spirv =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %BaseColor %OutColor
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %BaseColor "BaseColor"
- OpName %d "d"
- OpName %OutColor "OutColor"
- OpDecorate %BaseColor Location 0
- OpDecorate %OutColor Location 0
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %BaseColor = OpVariable %_ptr_Input_v4float Input
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %_ptr_Input_float = OpTypePointer Input %float
- %float_0 = OpConstant %float 0
- %bool = OpTypeBool
- %_ptr_Function_float = OpTypePointer Function %float
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %OutColor = OpVariable %_ptr_Output_v4float Output
- ; CHECK: = OpFunction
- ; CHECK-NEXT: = OpLabel
- ; CHECK-NEXT: OpBranch [[target:%\w+]]
- ; CHECK-NEXT: [[target]] = OpLabel
- ; CHECK-NEXT: OpReturn
- ; CHECK-NEXT: OpFunctionEnd
- %main = OpFunction %void None %7
- %20 = OpLabel
- %d = OpVariable %_ptr_Function_float Function
- %21 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
- %22 = OpLoad %float %21
- %23 = OpFOrdEqual %bool %22 %float_0
- OpSelectionMerge %24 None
- OpBranchConditional %23 %25 %26
- %25 = OpLabel
- %27 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
- %28 = OpLoad %float %27
- OpStore %d %28
- OpBranch %24
- %26 = OpLabel
- %29 = OpAccessChain %_ptr_Input_float %BaseColor %uint_2
- %30 = OpLoad %float %29
- OpStore %d %30
- OpBranch %24
- %24 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, EliminateUselessInnerLoop) {
- // #version 430
- //
- // layout(std430) buffer U_t
- // {
- // float g_F[10];
- // };
- //
- // layout(location = 0)out float o;
- //
- // void main(void)
- // {
- // float s = 0.0;
- // for (int i=0; i<10; i++) {
- // for (int j=0; j<10; j++) {
- // }
- // s += g_F[i];
- // }
- // o = s;
- // }
- const std::string predefs_before =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %s "s"
- OpName %i "i"
- OpName %j "j"
- OpName %U_t "U_t"
- OpMemberName %U_t 0 "g_F"
- OpName %_ ""
- OpName %o "o"
- OpDecorate %_arr_float_uint_10 ArrayStride 4
- OpMemberDecorate %U_t 0 Offset 0
- OpDecorate %U_t BufferBlock
- OpDecorate %_ DescriptorSet 0
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %11 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %int_0 = OpConstant %int 0
- %int_10 = OpConstant %int 10
- %bool = OpTypeBool
- %int_1 = OpConstant %int 1
- %uint = OpTypeInt 32 0
- %uint_10 = OpConstant %uint 10
- %_arr_float_uint_10 = OpTypeArray %float %uint_10
- %U_t = OpTypeStruct %_arr_float_uint_10
- %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
- %_ = OpVariable %_ptr_Uniform_U_t Uniform
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %_ptr_Output_float = OpTypePointer Output %float
- %o = OpVariable %_ptr_Output_float Output
- )";
- const std::string predefs_after =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %s "s"
- OpName %i "i"
- OpName %U_t "U_t"
- OpMemberName %U_t 0 "g_F"
- OpName %_ ""
- OpName %o "o"
- OpDecorate %_arr_float_uint_10 ArrayStride 4
- OpMemberDecorate %U_t 0 Offset 0
- OpDecorate %U_t BufferBlock
- OpDecorate %_ DescriptorSet 0
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %11 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %int_0 = OpConstant %int 0
- %int_10 = OpConstant %int 10
- %bool = OpTypeBool
- %int_1 = OpConstant %int 1
- %uint = OpTypeInt 32 0
- %uint_10 = OpConstant %uint 10
- %_arr_float_uint_10 = OpTypeArray %float %uint_10
- %U_t = OpTypeStruct %_arr_float_uint_10
- %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
- %_ = OpVariable %_ptr_Uniform_U_t Uniform
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %_ptr_Output_float = OpTypePointer Output %float
- %o = OpVariable %_ptr_Output_float Output
- )";
- const std::string func_before =
- R"(%main = OpFunction %void None %11
- %26 = OpLabel
- %s = OpVariable %_ptr_Function_float Function
- %i = OpVariable %_ptr_Function_int Function
- %j = OpVariable %_ptr_Function_int Function
- OpStore %s %float_0
- OpStore %i %int_0
- OpBranch %27
- %27 = OpLabel
- OpLoopMerge %28 %29 None
- OpBranch %30
- %30 = OpLabel
- %31 = OpLoad %int %i
- %32 = OpSLessThan %bool %31 %int_10
- OpBranchConditional %32 %33 %28
- %33 = OpLabel
- OpStore %j %int_0
- OpBranch %34
- %34 = OpLabel
- OpLoopMerge %35 %36 None
- OpBranch %37
- %37 = OpLabel
- %38 = OpLoad %int %j
- %39 = OpSLessThan %bool %38 %int_10
- OpBranchConditional %39 %40 %35
- %40 = OpLabel
- OpBranch %36
- %36 = OpLabel
- %41 = OpLoad %int %j
- %42 = OpIAdd %int %41 %int_1
- OpStore %j %42
- OpBranch %34
- %35 = OpLabel
- %43 = OpLoad %int %i
- %44 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %43
- %45 = OpLoad %float %44
- %46 = OpLoad %float %s
- %47 = OpFAdd %float %46 %45
- OpStore %s %47
- OpBranch %29
- %29 = OpLabel
- %48 = OpLoad %int %i
- %49 = OpIAdd %int %48 %int_1
- OpStore %i %49
- OpBranch %27
- %28 = OpLabel
- %50 = OpLoad %float %s
- OpStore %o %50
- OpReturn
- OpFunctionEnd
- )";
- const std::string func_after =
- R"(%main = OpFunction %void None %11
- %26 = OpLabel
- %s = OpVariable %_ptr_Function_float Function
- %i = OpVariable %_ptr_Function_int Function
- OpStore %s %float_0
- OpStore %i %int_0
- OpBranch %27
- %27 = OpLabel
- OpLoopMerge %28 %29 None
- OpBranch %30
- %30 = OpLabel
- %31 = OpLoad %int %i
- %32 = OpSLessThan %bool %31 %int_10
- OpBranchConditional %32 %33 %28
- %33 = OpLabel
- OpBranch %34
- %34 = OpLabel
- OpBranch %35
- %35 = OpLabel
- %43 = OpLoad %int %i
- %44 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %43
- %45 = OpLoad %float %44
- %46 = OpLoad %float %s
- %47 = OpFAdd %float %46 %45
- OpStore %s %47
- OpBranch %29
- %29 = OpLabel
- %48 = OpLoad %int %i
- %49 = OpIAdd %int %48 %int_1
- OpStore %i %49
- OpBranch %27
- %28 = OpLabel
- %50 = OpLoad %float %s
- OpStore %o %50
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(
- predefs_before + func_before, predefs_after + func_after, true, true);
- }
- TEST_F(AggressiveDCETest, EliminateUselessNestedLoopWithIf) {
- // #version 430
- //
- // layout(std430) buffer U_t
- // {
- // float g_F[10][10];
- // };
- //
- // layout(location = 0)out float o;
- //
- // void main(void)
- // {
- // float s = 0.0;
- // for (int i=0; i<10; i++) {
- // for (int j=0; j<10; j++) {
- // float t = g_F[i][j];
- // if (t > 0.0)
- // s += t;
- // }
- // }
- // o = 0.0;
- // }
- const std::string predefs_before =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %s "s"
- OpName %i "i"
- OpName %j "j"
- OpName %U_t "U_t"
- OpMemberName %U_t 0 "g_F"
- OpName %_ ""
- OpName %o "o"
- OpDecorate %_arr_float_uint_10 ArrayStride 4
- OpDecorate %_arr__arr_float_uint_10_uint_10 ArrayStride 40
- OpMemberDecorate %U_t 0 Offset 0
- OpDecorate %U_t BufferBlock
- OpDecorate %_ DescriptorSet 0
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %12 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %int_0 = OpConstant %int 0
- %int_10 = OpConstant %int 10
- %bool = OpTypeBool
- %uint = OpTypeInt 32 0
- %uint_10 = OpConstant %uint 10
- %_arr_float_uint_10 = OpTypeArray %float %uint_10
- %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
- %U_t = OpTypeStruct %_arr__arr_float_uint_10_uint_10
- %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
- %_ = OpVariable %_ptr_Uniform_U_t Uniform
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %int_1 = OpConstant %int 1
- %_ptr_Output_float = OpTypePointer Output %float
- %o = OpVariable %_ptr_Output_float Output
- )";
- const std::string predefs_after =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %o "o"
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %12 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %_ptr_Output_float = OpTypePointer Output %float
- %o = OpVariable %_ptr_Output_float Output
- )";
- const std::string func_before =
- R"(%main = OpFunction %void None %12
- %27 = OpLabel
- %s = OpVariable %_ptr_Function_float Function
- %i = OpVariable %_ptr_Function_int Function
- %j = OpVariable %_ptr_Function_int Function
- OpStore %s %float_0
- OpStore %i %int_0
- OpBranch %28
- %28 = OpLabel
- OpLoopMerge %29 %30 None
- OpBranch %31
- %31 = OpLabel
- %32 = OpLoad %int %i
- %33 = OpSLessThan %bool %32 %int_10
- OpBranchConditional %33 %34 %29
- %34 = OpLabel
- OpStore %j %int_0
- OpBranch %35
- %35 = OpLabel
- OpLoopMerge %36 %37 None
- OpBranch %38
- %38 = OpLabel
- %39 = OpLoad %int %j
- %40 = OpSLessThan %bool %39 %int_10
- OpBranchConditional %40 %41 %36
- %41 = OpLabel
- %42 = OpLoad %int %i
- %43 = OpLoad %int %j
- %44 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %42 %43
- %45 = OpLoad %float %44
- %46 = OpFOrdGreaterThan %bool %45 %float_0
- OpSelectionMerge %47 None
- OpBranchConditional %46 %48 %47
- %48 = OpLabel
- %49 = OpLoad %float %s
- %50 = OpFAdd %float %49 %45
- OpStore %s %50
- OpBranch %47
- %47 = OpLabel
- OpBranch %37
- %37 = OpLabel
- %51 = OpLoad %int %j
- %52 = OpIAdd %int %51 %int_1
- OpStore %j %52
- OpBranch %35
- %36 = OpLabel
- OpBranch %30
- %30 = OpLabel
- %53 = OpLoad %int %i
- %54 = OpIAdd %int %53 %int_1
- OpStore %i %54
- OpBranch %28
- %29 = OpLabel
- OpStore %o %float_0
- OpReturn
- OpFunctionEnd
- )";
- const std::string func_after =
- R"(%main = OpFunction %void None %12
- %27 = OpLabel
- OpBranch %28
- %28 = OpLabel
- OpBranch %29
- %29 = OpLabel
- OpStore %o %float_0
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(
- predefs_before + func_before, predefs_after + func_after, true, true);
- }
- TEST_F(AggressiveDCETest, EliminateEmptyIfBeforeContinue) {
- // #version 430
- //
- // layout(location = 0)out float o;
- //
- // void main(void)
- // {
- // float s = 0.0;
- // for (int i=0; i<10; i++) {
- // s += 1.0;
- // if (i > s) {}
- // }
- // o = s;
- // }
- const std::string predefs_before =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %3
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
- OpSourceExtension "GL_GOOGLE_include_directive"
- OpName %main "main"
- OpDecorate %3 Location 0
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %int_0 = OpConstant %int 0
- %int_10 = OpConstant %int 10
- %bool = OpTypeBool
- %float_1 = OpConstant %float 1
- %int_1 = OpConstant %int 1
- %_ptr_Output_float = OpTypePointer Output %float
- %3 = OpVariable %_ptr_Output_float Output
- )";
- const std::string predefs_after =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %3
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
- OpSourceExtension "GL_GOOGLE_include_directive"
- OpName %main "main"
- OpDecorate %3 Location 0
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %int_10 = OpConstant %int 10
- %bool = OpTypeBool
- %float_1 = OpConstant %float 1
- %int_1 = OpConstant %int 1
- %_ptr_Output_float = OpTypePointer Output %float
- %3 = OpVariable %_ptr_Output_float Output
- )";
- const std::string func_before =
- R"(%main = OpFunction %void None %5
- %16 = OpLabel
- OpBranch %17
- %17 = OpLabel
- %18 = OpPhi %float %float_0 %16 %19 %20
- %21 = OpPhi %int %int_0 %16 %22 %20
- OpLoopMerge %23 %20 None
- OpBranch %24
- %24 = OpLabel
- %25 = OpSLessThan %bool %21 %int_10
- OpBranchConditional %25 %26 %23
- %26 = OpLabel
- %19 = OpFAdd %float %18 %float_1
- %27 = OpConvertFToS %int %19
- %28 = OpSGreaterThan %bool %21 %27
- OpSelectionMerge %20 None
- OpBranchConditional %28 %29 %20
- %29 = OpLabel
- OpBranch %20
- %20 = OpLabel
- %22 = OpIAdd %int %21 %int_1
- OpBranch %17
- %23 = OpLabel
- OpStore %3 %18
- OpReturn
- OpFunctionEnd
- )";
- const std::string func_after =
- R"(%main = OpFunction %void None %5
- %16 = OpLabel
- OpBranch %17
- %17 = OpLabel
- %18 = OpPhi %float %float_0 %16 %19 %20
- %21 = OpPhi %int %int_0 %16 %22 %20
- OpLoopMerge %23 %20 None
- OpBranch %24
- %24 = OpLabel
- %25 = OpSLessThan %bool %21 %int_10
- OpBranchConditional %25 %26 %23
- %26 = OpLabel
- %19 = OpFAdd %float %18 %float_1
- OpBranch %20
- %20 = OpLabel
- %22 = OpIAdd %int %21 %int_1
- OpBranch %17
- %23 = OpLabel
- OpStore %3 %18
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(
- predefs_before + func_before, predefs_after + func_after, true, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateLiveNestedLoopWithIf) {
- // Note: SPIR-V optimized
- //
- // #version 430
- //
- // layout(std430) buffer U_t
- // {
- // float g_F[10][10];
- // };
- //
- // layout(location = 0)out float o;
- //
- // void main(void)
- // {
- // float s = 0.0;
- // for (int i=0; i<10; i++) {
- // for (int j=0; j<10; j++) {
- // float t = g_F[i][j];
- // if (t > 0.0)
- // s += t;
- // }
- // }
- // o = s;
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %s "s"
- OpName %i "i"
- OpName %j "j"
- OpName %U_t "U_t"
- OpMemberName %U_t 0 "g_F"
- OpName %_ ""
- OpName %o "o"
- OpDecorate %_arr_float_uint_10 ArrayStride 4
- OpDecorate %_arr__arr_float_uint_10_uint_10 ArrayStride 40
- OpMemberDecorate %U_t 0 Offset 0
- OpDecorate %U_t BufferBlock
- OpDecorate %_ DescriptorSet 0
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %12 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %int_0 = OpConstant %int 0
- %int_10 = OpConstant %int 10
- %bool = OpTypeBool
- %uint = OpTypeInt 32 0
- %uint_10 = OpConstant %uint 10
- %_arr_float_uint_10 = OpTypeArray %float %uint_10
- %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
- %U_t = OpTypeStruct %_arr__arr_float_uint_10_uint_10
- %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
- %_ = OpVariable %_ptr_Uniform_U_t Uniform
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %int_1 = OpConstant %int 1
- %_ptr_Output_float = OpTypePointer Output %float
- %o = OpVariable %_ptr_Output_float Output
- %main = OpFunction %void None %12
- %27 = OpLabel
- %s = OpVariable %_ptr_Function_float Function
- %i = OpVariable %_ptr_Function_int Function
- %j = OpVariable %_ptr_Function_int Function
- OpStore %s %float_0
- OpStore %i %int_0
- OpBranch %28
- %28 = OpLabel
- OpLoopMerge %29 %30 None
- OpBranch %31
- %31 = OpLabel
- %32 = OpLoad %int %i
- %33 = OpSLessThan %bool %32 %int_10
- OpBranchConditional %33 %34 %29
- %34 = OpLabel
- OpStore %j %int_0
- OpBranch %35
- %35 = OpLabel
- OpLoopMerge %36 %37 None
- OpBranch %38
- %38 = OpLabel
- %39 = OpLoad %int %j
- %40 = OpSLessThan %bool %39 %int_10
- OpBranchConditional %40 %41 %36
- %41 = OpLabel
- %42 = OpLoad %int %i
- %43 = OpLoad %int %j
- %44 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %42 %43
- %45 = OpLoad %float %44
- %46 = OpFOrdGreaterThan %bool %45 %float_0
- OpSelectionMerge %47 None
- OpBranchConditional %46 %48 %47
- %48 = OpLabel
- %49 = OpLoad %float %s
- %50 = OpFAdd %float %49 %45
- OpStore %s %50
- OpBranch %47
- %47 = OpLabel
- OpBranch %37
- %37 = OpLabel
- %51 = OpLoad %int %j
- %52 = OpIAdd %int %51 %int_1
- OpStore %j %52
- OpBranch %35
- %36 = OpLabel
- OpBranch %30
- %30 = OpLabel
- %53 = OpLoad %int %i
- %54 = OpIAdd %int %53 %int_1
- OpStore %i %54
- OpBranch %28
- %29 = OpLabel
- %55 = OpLoad %float %s
- OpStore %o %55
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateIfContinue) {
- // Do not eliminate continue embedded in if construct
- //
- // #version 430
- //
- // layout(std430) buffer U_t
- // {
- // float g_F[10];
- // };
- //
- // layout(location = 0)out float o;
- //
- // void main(void)
- // {
- // float s = 0.0;
- // for (int i=0; i<10; i++) {
- // if (i % 2 == 0) continue;
- // s += g_F[i];
- // }
- // o = s;
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %s "s"
- OpName %i "i"
- OpName %U_t "U_t"
- OpMemberName %U_t 0 "g_F"
- OpName %_ ""
- OpName %o "o"
- OpDecorate %_arr_float_uint_10 ArrayStride 4
- OpMemberDecorate %U_t 0 Offset 0
- OpDecorate %U_t BufferBlock
- OpDecorate %_ DescriptorSet 0
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %10 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %int_0 = OpConstant %int 0
- %int_10 = OpConstant %int 10
- %bool = OpTypeBool
- %int_2 = OpConstant %int 2
- %uint = OpTypeInt 32 0
- %uint_10 = OpConstant %uint 10
- %_arr_float_uint_10 = OpTypeArray %float %uint_10
- %U_t = OpTypeStruct %_arr_float_uint_10
- %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
- %_ = OpVariable %_ptr_Uniform_U_t Uniform
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %int_1 = OpConstant %int 1
- %_ptr_Output_float = OpTypePointer Output %float
- %o = OpVariable %_ptr_Output_float Output
- %main = OpFunction %void None %10
- %26 = OpLabel
- %s = OpVariable %_ptr_Function_float Function
- %i = OpVariable %_ptr_Function_int Function
- OpStore %s %float_0
- OpStore %i %int_0
- OpBranch %27
- %27 = OpLabel
- OpLoopMerge %28 %29 None
- OpBranch %30
- %30 = OpLabel
- %31 = OpLoad %int %i
- %32 = OpSLessThan %bool %31 %int_10
- OpBranchConditional %32 %33 %28
- %33 = OpLabel
- %34 = OpLoad %int %i
- %35 = OpSMod %int %34 %int_2
- %36 = OpIEqual %bool %35 %int_0
- OpSelectionMerge %37 None
- OpBranchConditional %36 %38 %37
- %38 = OpLabel
- OpBranch %29
- %37 = OpLabel
- %39 = OpLoad %int %i
- %40 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %39
- %41 = OpLoad %float %40
- %42 = OpLoad %float %s
- %43 = OpFAdd %float %42 %41
- OpStore %s %43
- OpBranch %29
- %29 = OpLabel
- %44 = OpLoad %int %i
- %45 = OpIAdd %int %44 %int_1
- OpStore %i %45
- OpBranch %27
- %28 = OpLabel
- %46 = OpLoad %float %s
- OpStore %o %46
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateIfContinue2) {
- // Do not eliminate continue not embedded in if construct
- //
- // #version 430
- //
- // layout(std430) buffer U_t
- // {
- // float g_F[10];
- // };
- //
- // layout(location = 0)out float o;
- //
- // void main(void)
- // {
- // float s = 0.0;
- // for (int i=0; i<10; i++) {
- // if (i % 2 == 0) continue;
- // s += g_F[i];
- // }
- // o = s;
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %s "s"
- OpName %i "i"
- OpName %U_t "U_t"
- OpMemberName %U_t 0 "g_F"
- OpName %_ ""
- OpName %o "o"
- OpDecorate %_arr_float_uint_10 ArrayStride 4
- OpMemberDecorate %U_t 0 Offset 0
- OpDecorate %U_t BufferBlock
- OpDecorate %_ DescriptorSet 0
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %10 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %int_0 = OpConstant %int 0
- %int_10 = OpConstant %int 10
- %bool = OpTypeBool
- %int_2 = OpConstant %int 2
- %uint = OpTypeInt 32 0
- %uint_10 = OpConstant %uint 10
- %_arr_float_uint_10 = OpTypeArray %float %uint_10
- %U_t = OpTypeStruct %_arr_float_uint_10
- %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
- %_ = OpVariable %_ptr_Uniform_U_t Uniform
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %int_1 = OpConstant %int 1
- %_ptr_Output_float = OpTypePointer Output %float
- %o = OpVariable %_ptr_Output_float Output
- %main = OpFunction %void None %10
- %26 = OpLabel
- %s = OpVariable %_ptr_Function_float Function
- %i = OpVariable %_ptr_Function_int Function
- OpStore %s %float_0
- OpStore %i %int_0
- OpBranch %27
- %27 = OpLabel
- OpLoopMerge %28 %29 None
- OpBranch %30
- %30 = OpLabel
- %31 = OpLoad %int %i
- %32 = OpSLessThan %bool %31 %int_10
- OpBranchConditional %32 %33 %28
- %33 = OpLabel
- %34 = OpLoad %int %i
- %35 = OpSMod %int %34 %int_2
- %36 = OpIEqual %bool %35 %int_0
- OpBranchConditional %36 %29 %37
- %37 = OpLabel
- %38 = OpLoad %int %i
- %39 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %38
- %40 = OpLoad %float %39
- %41 = OpLoad %float %s
- %42 = OpFAdd %float %41 %40
- OpStore %s %42
- OpBranch %29
- %29 = OpLabel
- %43 = OpLoad %int %i
- %44 = OpIAdd %int %43 %int_1
- OpStore %i %44
- OpBranch %27
- %28 = OpLabel
- %45 = OpLoad %float %s
- OpStore %o %45
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateIfContinue3) {
- // Do not eliminate continue as conditional branch with merge instruction
- // Note: SPIR-V edited to add merge instruction before continue.
- //
- // #version 430
- //
- // layout(std430) buffer U_t
- // {
- // float g_F[10];
- // };
- //
- // layout(location = 0)out float o;
- //
- // void main(void)
- // {
- // float s = 0.0;
- // for (int i=0; i<10; i++) {
- // if (i % 2 == 0) continue;
- // s += g_F[i];
- // }
- // o = s;
- // }
- const std::string assembly =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %s "s"
- OpName %i "i"
- OpName %U_t "U_t"
- OpMemberName %U_t 0 "g_F"
- OpName %_ ""
- OpName %o "o"
- OpDecorate %_arr_float_uint_10 ArrayStride 4
- OpMemberDecorate %U_t 0 Offset 0
- OpDecorate %U_t BufferBlock
- OpDecorate %_ DescriptorSet 0
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %10 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %float_0 = OpConstant %float 0
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %int_0 = OpConstant %int 0
- %int_10 = OpConstant %int 10
- %bool = OpTypeBool
- %int_2 = OpConstant %int 2
- %uint = OpTypeInt 32 0
- %uint_10 = OpConstant %uint 10
- %_arr_float_uint_10 = OpTypeArray %float %uint_10
- %U_t = OpTypeStruct %_arr_float_uint_10
- %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
- %_ = OpVariable %_ptr_Uniform_U_t Uniform
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %int_1 = OpConstant %int 1
- %_ptr_Output_float = OpTypePointer Output %float
- %o = OpVariable %_ptr_Output_float Output
- %main = OpFunction %void None %10
- %26 = OpLabel
- %s = OpVariable %_ptr_Function_float Function
- %i = OpVariable %_ptr_Function_int Function
- OpStore %s %float_0
- OpStore %i %int_0
- OpBranch %27
- %27 = OpLabel
- OpLoopMerge %28 %29 None
- OpBranch %30
- %30 = OpLabel
- %31 = OpLoad %int %i
- %32 = OpSLessThan %bool %31 %int_10
- OpBranchConditional %32 %33 %28
- %33 = OpLabel
- %34 = OpLoad %int %i
- %35 = OpSMod %int %34 %int_2
- %36 = OpIEqual %bool %35 %int_0
- OpSelectionMerge %37 None
- OpBranchConditional %36 %29 %37
- %37 = OpLabel
- %38 = OpLoad %int %i
- %39 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %38
- %40 = OpLoad %float %39
- %41 = OpLoad %float %s
- %42 = OpFAdd %float %41 %40
- OpStore %s %42
- OpBranch %29
- %29 = OpLabel
- %43 = OpLoad %int %i
- %44 = OpIAdd %int %43 %int_1
- OpStore %i %44
- OpBranch %27
- %28 = OpLabel
- %45 = OpLoad %float %s
- OpStore %o %45
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
- }
- // This is not valid input and ADCE does not support variable pointers and only
- // supports shaders.
- TEST_F(AggressiveDCETest, PointerVariable) {
- // ADCE is able to handle code that contains a load whose base address
- // comes from a load and not an OpVariable. I want to see an instruction
- // removed to be sure that ADCE is not exiting early.
- const std::string before =
- R"(OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main" %2
- OpExecutionMode %1 OriginUpperLeft
- OpMemberDecorate %_struct_3 0 Offset 0
- OpDecorate %_runtimearr__struct_3 ArrayStride 16
- OpMemberDecorate %_struct_5 0 Offset 0
- OpDecorate %_struct_5 BufferBlock
- OpMemberDecorate %_struct_6 0 Offset 0
- OpDecorate %_struct_6 BufferBlock
- OpDecorate %2 Location 0
- OpDecorate %7 DescriptorSet 0
- OpDecorate %7 Binding 0
- OpDecorate %8 DescriptorSet 0
- OpDecorate %8 Binding 1
- %void = OpTypeVoid
- %10 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %uint = OpTypeInt 32 0
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
- %_struct_3 = OpTypeStruct %v4float
- %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
- %_struct_5 = OpTypeStruct %_runtimearr__struct_3
- %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
- %_struct_6 = OpTypeStruct %int
- %_ptr_Uniform__struct_6 = OpTypePointer Uniform %_struct_6
- %_ptr_Function__ptr_Uniform__struct_5 = OpTypePointer Function %_ptr_Uniform__struct_5
- %_ptr_Function__ptr_Uniform__struct_6 = OpTypePointer Function %_ptr_Uniform__struct_6
- %int_0 = OpConstant %int 0
- %uint_0 = OpConstant %uint 0
- %2 = OpVariable %_ptr_Output_v4float Output
- %7 = OpVariable %_ptr_Uniform__struct_5 Uniform
- %8 = OpVariable %_ptr_Uniform__struct_6 Uniform
- %1 = OpFunction %void None %10
- %23 = OpLabel
- %24 = OpVariable %_ptr_Function__ptr_Uniform__struct_5 Function
- OpStore %24 %7
- %26 = OpLoad %_ptr_Uniform__struct_5 %24
- %27 = OpAccessChain %_ptr_Uniform_v4float %26 %int_0 %uint_0 %int_0
- %28 = OpLoad %v4float %27
- %29 = OpCopyObject %v4float %28
- OpStore %2 %28
- OpReturn
- OpFunctionEnd
- )";
- const std::string after =
- R"(OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main" %2
- OpExecutionMode %1 OriginUpperLeft
- OpMemberDecorate %_struct_3 0 Offset 0
- OpDecorate %_runtimearr__struct_3 ArrayStride 16
- OpMemberDecorate %_struct_5 0 Offset 0
- OpDecorate %_struct_5 BufferBlock
- OpDecorate %2 Location 0
- OpDecorate %7 DescriptorSet 0
- OpDecorate %7 Binding 0
- %void = OpTypeVoid
- %10 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %uint = OpTypeInt 32 0
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
- %_struct_3 = OpTypeStruct %v4float
- %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
- %_struct_5 = OpTypeStruct %_runtimearr__struct_3
- %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
- %_ptr_Function__ptr_Uniform__struct_5 = OpTypePointer Function %_ptr_Uniform__struct_5
- %int_0 = OpConstant %int 0
- %uint_0 = OpConstant %uint 0
- %2 = OpVariable %_ptr_Output_v4float Output
- %7 = OpVariable %_ptr_Uniform__struct_5 Uniform
- %1 = OpFunction %void None %10
- %23 = OpLabel
- %24 = OpVariable %_ptr_Function__ptr_Uniform__struct_5 Function
- OpStore %24 %7
- %25 = OpLoad %_ptr_Uniform__struct_5 %24
- %26 = OpAccessChain %_ptr_Uniform_v4float %25 %int_0 %uint_0 %int_0
- %27 = OpLoad %v4float %26
- OpStore %2 %27
- OpReturn
- OpFunctionEnd
- )";
- // The input is not valid and ADCE only supports shaders, but not variable
- // pointers. Workaround this by enabling relaxed logical pointers in the
- // validator.
- ValidatorOptions()->relax_logical_pointer = true;
- SinglePassRunAndCheck<AggressiveDCEPass>(before, after, true, true);
- }
- // %dead is unused. Make sure we remove it along with its name.
- TEST_F(AggressiveDCETest, RemoveUnreferenced) {
- const std::string before =
- R"(OpCapability Shader
- OpCapability Linkage
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 150
- OpName %main "main"
- OpName %dead "dead"
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Private_float = OpTypePointer Private %float
- %dead = OpVariable %_ptr_Private_float Private
- %main = OpFunction %void None %5
- %8 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- const std::string after =
- R"(OpCapability Shader
- OpCapability Linkage
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 150
- OpName %main "main"
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %main = OpFunction %void None %5
- %8 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(before, after, true, true);
- }
- // Delete %dead because it is unreferenced. Then %initializer becomes
- // unreferenced, so remove it as well.
- TEST_F(AggressiveDCETest, RemoveUnreferencedWithInit1) {
- const std::string before =
- R"(OpCapability Shader
- OpCapability Linkage
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 150
- OpName %main "main"
- OpName %dead "dead"
- OpName %initializer "initializer"
- %void = OpTypeVoid
- %6 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Private_float = OpTypePointer Private %float
- %initializer = OpVariable %_ptr_Private_float Private
- %dead = OpVariable %_ptr_Private_float Private %initializer
- %main = OpFunction %void None %6
- %9 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- const std::string after =
- R"(OpCapability Shader
- OpCapability Linkage
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 150
- OpName %main "main"
- %void = OpTypeVoid
- %6 = OpTypeFunction %void
- %main = OpFunction %void None %6
- %9 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(before, after, true, true);
- }
- // Keep %live because it is used, and its initializer.
- TEST_F(AggressiveDCETest, KeepReferenced) {
- const std::string before =
- R"(OpCapability Shader
- OpCapability Linkage
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %output
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 150
- OpName %main "main"
- OpName %live "live"
- OpName %initializer "initializer"
- OpName %output "output"
- %void = OpTypeVoid
- %6 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Private_float = OpTypePointer Private %float
- %initializer = OpConstant %float 0
- %live = OpVariable %_ptr_Private_float Private %initializer
- %_ptr_Output_float = OpTypePointer Output %float
- %output = OpVariable %_ptr_Output_float Output
- %main = OpFunction %void None %6
- %9 = OpLabel
- %10 = OpLoad %float %live
- OpStore %output %10
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(before, before, true, true);
- }
- // This test that the decoration associated with a variable are removed when the
- // variable is removed.
- TEST_F(AggressiveDCETest, RemoveVariableAndDecorations) {
- const std::string before =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpName %main "main"
- OpName %B "B"
- OpMemberName %B 0 "a"
- OpName %Bdat "Bdat"
- OpMemberDecorate %B 0 Offset 0
- OpDecorate %B BufferBlock
- OpDecorate %Bdat DescriptorSet 0
- OpDecorate %Bdat Binding 0
- %void = OpTypeVoid
- %6 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %B = OpTypeStruct %uint
- %_ptr_Uniform_B = OpTypePointer Uniform %B
- %Bdat = OpVariable %_ptr_Uniform_B Uniform
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %uint_1 = OpConstant %uint 1
- %_ptr_Uniform_uint = OpTypePointer Uniform %uint
- %main = OpFunction %void None %6
- %13 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- const std::string after =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource GLSL 450
- OpName %main "main"
- %void = OpTypeVoid
- %6 = OpTypeFunction %void
- %main = OpFunction %void None %6
- %13 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(before, after, true, true);
- }
- TEST_F(AggressiveDCETest, DeadNestedSwitch) {
- const std::string text = R"(
- ; CHECK: OpLabel
- ; CHECK: OpBranch [[block:%\w+]]
- ; CHECK-NOT: OpSwitch
- ; CHECK-NEXT: [[block]] = OpLabel
- ; CHECK: OpBranch [[block:%\w+]]
- ; CHECK-NOT: OpSwitch
- ; CHECK-NEXT: [[block]] = OpLabel
- ; CHECK-NEXT: OpStore
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %func "func" %x
- OpExecutionMode %func OriginUpperLeft
- OpName %func "func"
- %void = OpTypeVoid
- %1 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %uint_ptr_Output = OpTypePointer Output %uint
- %uint_ptr_Input = OpTypePointer Input %uint
- %x = OpVariable %uint_ptr_Output Output
- %a = OpVariable %uint_ptr_Input Input
- %func = OpFunction %void None %1
- %entry = OpLabel
- OpBranch %header
- %header = OpLabel
- %ld = OpLoad %uint %a
- OpLoopMerge %merge %continue None
- OpBranch %postheader
- %postheader = OpLabel
- ; This switch doesn't require an OpSelectionMerge and is nested in the dead loop.
- OpSwitch %ld %merge 0 %extra 1 %continue
- %extra = OpLabel
- OpBranch %continue
- %continue = OpLabel
- OpBranch %header
- %merge = OpLabel
- OpStore %x %uint_0
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, LiveNestedSwitch) {
- const std::string text = R"(OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %func "func" %3 %10
- OpExecutionMode %func OriginUpperLeft
- OpName %func "func"
- %void = OpTypeVoid
- %1 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %uint_1 = OpConstant %uint 1
- %_ptr_Output_uint = OpTypePointer Output %uint
- %_ptr_Input_uint = OpTypePointer Input %uint
- %3 = OpVariable %_ptr_Output_uint Output
- %10 = OpVariable %_ptr_Input_uint Input
- %func = OpFunction %void None %1
- %11 = OpLabel
- OpBranch %12
- %12 = OpLabel
- %13 = OpLoad %uint %10
- OpLoopMerge %14 %15 None
- OpBranch %16
- %16 = OpLabel
- OpSelectionMerge %18 None
- OpSwitch %13 %18 0 %17 1 %19
- %17 = OpLabel
- OpStore %3 %uint_1
- OpBranch %19
- %19 = OpLabel
- OpBranch %15
- %15 = OpLabel
- OpBranch %12
- %18 = OpLabel
- OpBranch %14
- %14 = OpLabel
- OpStore %3 %uint_0
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(text, text, false, true);
- }
- TEST_F(AggressiveDCETest, BasicDeleteDeadFunction) {
- // The function Dead should be removed because it is never called.
- const std::vector<const char*> common_code = {
- // clang-format off
- "OpCapability Shader",
- "OpMemoryModel Logical GLSL450",
- "OpEntryPoint Fragment %main \"main\"",
- "OpName %main \"main\"",
- "OpName %Live \"Live\"",
- "%void = OpTypeVoid",
- "%7 = OpTypeFunction %void",
- "%main = OpFunction %void None %7",
- "%15 = OpLabel",
- "%16 = OpFunctionCall %void %Live",
- "%17 = OpFunctionCall %void %Live",
- "OpReturn",
- "OpFunctionEnd",
- "%Live = OpFunction %void None %7",
- "%20 = OpLabel",
- "OpReturn",
- "OpFunctionEnd"
- // clang-format on
- };
- const std::vector<const char*> dead_function = {
- // clang-format off
- "%Dead = OpFunction %void None %7",
- "%19 = OpLabel",
- "OpReturn",
- "OpFunctionEnd",
- // clang-format on
- };
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(
- JoinAllInsts(Concat(common_code, dead_function)),
- JoinAllInsts(common_code), /* skip_nop = */ true);
- }
- TEST_F(AggressiveDCETest, BasicKeepLiveFunction) {
- // Everything is reachable from an entry point, so no functions should be
- // deleted.
- const std::vector<const char*> text = {
- // clang-format off
- "OpCapability Shader",
- "OpMemoryModel Logical GLSL450",
- "OpEntryPoint Fragment %main \"main\"",
- "OpName %main \"main\"",
- "OpName %Live1 \"Live1\"",
- "OpName %Live2 \"Live2\"",
- "%void = OpTypeVoid",
- "%7 = OpTypeFunction %void",
- "%main = OpFunction %void None %7",
- "%15 = OpLabel",
- "%16 = OpFunctionCall %void %Live2",
- "%17 = OpFunctionCall %void %Live1",
- "OpReturn",
- "OpFunctionEnd",
- "%Live1 = OpFunction %void None %7",
- "%19 = OpLabel",
- "OpReturn",
- "OpFunctionEnd",
- "%Live2 = OpFunction %void None %7",
- "%20 = OpLabel",
- "OpReturn",
- "OpFunctionEnd"
- // clang-format on
- };
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- std::string assembly = JoinAllInsts(text);
- auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
- assembly, /* skip_nop = */ true, /* do_validation = */ false);
- EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
- EXPECT_EQ(assembly, std::get<0>(result));
- }
- TEST_F(AggressiveDCETest, BasicRemoveDecorationsAndNames) {
- // We want to remove the names and decorations associated with results that
- // are removed. This test will check for that.
- const std::string text = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpName %main "main"
- OpName %Dead "Dead"
- OpName %x "x"
- OpName %y "y"
- OpName %z "z"
- OpDecorate %x RelaxedPrecision
- OpDecorate %y RelaxedPrecision
- OpDecorate %z RelaxedPrecision
- OpDecorate %6 RelaxedPrecision
- OpDecorate %7 RelaxedPrecision
- OpDecorate %8 RelaxedPrecision
- %void = OpTypeVoid
- %10 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %_ptr_Function_float = OpTypePointer Function %float
- %float_1 = OpConstant %float 1
- %main = OpFunction %void None %10
- %14 = OpLabel
- OpReturn
- OpFunctionEnd
- %Dead = OpFunction %void None %10
- %15 = OpLabel
- %x = OpVariable %_ptr_Function_float Function
- %y = OpVariable %_ptr_Function_float Function
- %z = OpVariable %_ptr_Function_float Function
- OpStore %x %float_1
- OpStore %y %float_1
- %6 = OpLoad %float %x
- %7 = OpLoad %float %y
- %8 = OpFAdd %float %6 %7
- OpStore %z %8
- OpReturn
- OpFunctionEnd)";
- const std::string expected_output = R"(OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpName %main "main"
- %void = OpTypeVoid
- %10 = OpTypeFunction %void
- %main = OpFunction %void None %10
- %14 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(text, expected_output,
- /* skip_nop = */ true);
- }
- TEST_F(AggressiveDCETest, BasicAllDeadConstants) {
- const std::string text = R"(
- ; CHECK-NOT: OpConstant
- OpCapability Shader
- OpCapability Float64
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpName %main "main"
- %void = OpTypeVoid
- %4 = OpTypeFunction %void
- %bool = OpTypeBool
- %true = OpConstantTrue %bool
- %false = OpConstantFalse %bool
- %int = OpTypeInt 32 1
- %9 = OpConstant %int 1
- %uint = OpTypeInt 32 0
- %11 = OpConstant %uint 2
- %float = OpTypeFloat 32
- %13 = OpConstant %float 3.1415
- %double = OpTypeFloat 64
- %15 = OpConstant %double 3.14159265358979
- %main = OpFunction %void None %4
- %16 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, BasicNoneDeadConstants) {
- const std::vector<const char*> text = {
- // clang-format off
- "OpCapability Shader",
- "OpCapability Float64",
- "%1 = OpExtInstImport \"GLSL.std.450\"",
- "OpMemoryModel Logical GLSL450",
- "OpEntryPoint Vertex %main \"main\" %btv %bfv %iv %uv %fv %dv",
- "OpName %main \"main\"",
- "OpName %btv \"btv\"",
- "OpName %bfv \"bfv\"",
- "OpName %iv \"iv\"",
- "OpName %uv \"uv\"",
- "OpName %fv \"fv\"",
- "OpName %dv \"dv\"",
- "%void = OpTypeVoid",
- "%10 = OpTypeFunction %void",
- "%bool = OpTypeBool",
- "%_ptr_Output_bool = OpTypePointer Output %bool",
- "%true = OpConstantTrue %bool",
- "%false = OpConstantFalse %bool",
- "%int = OpTypeInt 32 1",
- "%_ptr_Output_int = OpTypePointer Output %int",
- "%int_1 = OpConstant %int 1",
- "%uint = OpTypeInt 32 0",
- "%_ptr_Output_uint = OpTypePointer Output %uint",
- "%uint_2 = OpConstant %uint 2",
- "%float = OpTypeFloat 32",
- "%_ptr_Output_float = OpTypePointer Output %float",
- "%float_3_1415 = OpConstant %float 3.1415",
- "%double = OpTypeFloat 64",
- "%_ptr_Output_double = OpTypePointer Output %double",
- "%double_3_14159265358979 = OpConstant %double 3.14159265358979",
- "%btv = OpVariable %_ptr_Output_bool Output",
- "%bfv = OpVariable %_ptr_Output_bool Output",
- "%iv = OpVariable %_ptr_Output_int Output",
- "%uv = OpVariable %_ptr_Output_uint Output",
- "%fv = OpVariable %_ptr_Output_float Output",
- "%dv = OpVariable %_ptr_Output_double Output",
- "%main = OpFunction %void None %10",
- "%27 = OpLabel",
- "OpStore %btv %true",
- "OpStore %bfv %false",
- "OpStore %iv %int_1",
- "OpStore %uv %uint_2",
- "OpStore %fv %float_3_1415",
- "OpStore %dv %double_3_14159265358979",
- "OpReturn",
- "OpFunctionEnd",
- // clang-format on
- };
- // All constants are used, so none of them should be eliminated.
- SinglePassRunAndCheck<AggressiveDCEPass>(
- JoinAllInsts(text), JoinAllInsts(text), /* skip_nop = */ true);
- }
- struct AggressiveEliminateDeadConstantTestCase {
- // Type declarations and constants that should be kept.
- std::vector<std::string> used_consts;
- // Instructions that refer to constants, this is added to create uses for
- // some constants so they won't be treated as dead constants.
- std::vector<std::string> main_insts;
- // Dead constants that should be removed.
- std::vector<std::string> dead_consts;
- // Expectations
- std::vector<std::string> checks;
- };
- // All types that are potentially required in
- // AggressiveEliminateDeadConstantTest.
- const std::vector<std::string> CommonTypes = {
- // clang-format off
- // scalar types
- "%bool = OpTypeBool",
- "%uint = OpTypeInt 32 0",
- "%int = OpTypeInt 32 1",
- "%float = OpTypeFloat 32",
- "%double = OpTypeFloat 64",
- // vector types
- "%v2bool = OpTypeVector %bool 2",
- "%v2uint = OpTypeVector %uint 2",
- "%v2int = OpTypeVector %int 2",
- "%v3int = OpTypeVector %int 3",
- "%v4int = OpTypeVector %int 4",
- "%v2float = OpTypeVector %float 2",
- "%v3float = OpTypeVector %float 3",
- "%v2double = OpTypeVector %double 2",
- // variable pointer types
- "%_pf_bool = OpTypePointer Output %bool",
- "%_pf_uint = OpTypePointer Output %uint",
- "%_pf_int = OpTypePointer Output %int",
- "%_pf_float = OpTypePointer Output %float",
- "%_pf_double = OpTypePointer Output %double",
- "%_pf_v2int = OpTypePointer Output %v2int",
- "%_pf_v3int = OpTypePointer Output %v3int",
- "%_pf_v2float = OpTypePointer Output %v2float",
- "%_pf_v3float = OpTypePointer Output %v3float",
- "%_pf_v2double = OpTypePointer Output %v2double",
- // struct types
- "%inner_struct = OpTypeStruct %bool %int %float %double",
- "%outer_struct = OpTypeStruct %inner_struct %int %double",
- "%flat_struct = OpTypeStruct %bool %int %float %double",
- // clang-format on
- };
- using AggressiveEliminateDeadConstantTest =
- PassTest<::testing::TestWithParam<AggressiveEliminateDeadConstantTestCase>>;
- TEST_P(AggressiveEliminateDeadConstantTest, Custom) {
- auto& tc = GetParam();
- AssemblyBuilder builder;
- builder.AppendTypesConstantsGlobals(CommonTypes)
- .AppendTypesConstantsGlobals(tc.used_consts)
- .AppendInMain(tc.main_insts);
- const std::string expected = builder.GetCode();
- builder.AppendTypesConstantsGlobals(tc.dead_consts);
- builder.PrependPreamble(tc.checks);
- const std::string assembly_with_dead_const = builder.GetCode();
- // Do not enable validation. As the input code is invalid from the base
- // tests (ported from other passes).
- SinglePassRunAndMatch<AggressiveDCEPass>(assembly_with_dead_const, false);
- }
- INSTANTIATE_TEST_SUITE_P(
- ScalarTypeConstants, AggressiveEliminateDeadConstantTest,
- ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
- // clang-format off
- // Scalar type constants, one dead constant and one used constant.
- {
- /* .used_consts = */
- {
- "%used_const_int = OpConstant %int 1",
- },
- /* .main_insts = */
- {
- "%int_var = OpVariable %_pf_int Output",
- "OpStore %int_var %used_const_int",
- },
- /* .dead_consts = */
- {
- "%dead_const_int = OpConstant %int 1",
- },
- /* .checks = */
- {
- "; CHECK: [[const:%\\w+]] = OpConstant %int 1",
- "; CHECK-NOT: OpConstant",
- "; CHECK: OpStore {{%\\w+}} [[const]]",
- },
- },
- {
- /* .used_consts = */
- {
- "%used_const_uint = OpConstant %uint 1",
- },
- /* .main_insts = */
- {
- "%uint_var = OpVariable %_pf_uint Output",
- "OpStore %uint_var %used_const_uint",
- },
- /* .dead_consts = */
- {
- "%dead_const_uint = OpConstant %uint 1",
- },
- /* .checks = */
- {
- "; CHECK: [[const:%\\w+]] = OpConstant %uint 1",
- "; CHECK-NOT: OpConstant",
- "; CHECK: OpStore {{%\\w+}} [[const]]",
- },
- },
- {
- /* .used_consts = */
- {
- "%used_const_float = OpConstant %float 3.1415",
- },
- /* .main_insts = */
- {
- "%float_var = OpVariable %_pf_float Output",
- "OpStore %float_var %used_const_float",
- },
- /* .dead_consts = */
- {
- "%dead_const_float = OpConstant %float 3.1415",
- },
- /* .checks = */
- {
- "; CHECK: [[const:%\\w+]] = OpConstant %float 3.1415",
- "; CHECK-NOT: OpConstant",
- "; CHECK: OpStore {{%\\w+}} [[const]]",
- },
- },
- {
- /* .used_consts = */
- {
- "%used_const_double = OpConstant %double 3.14",
- },
- /* .main_insts = */
- {
- "%double_var = OpVariable %_pf_double Output",
- "OpStore %double_var %used_const_double",
- },
- /* .dead_consts = */
- {
- "%dead_const_double = OpConstant %double 3.14",
- },
- /* .checks = */
- {
- "; CHECK: [[const:%\\w+]] = OpConstant %double 3.14",
- "; CHECK-NOT: OpConstant",
- "; CHECK: OpStore {{%\\w+}} [[const]]",
- },
- },
- // clang-format on
- })));
- INSTANTIATE_TEST_SUITE_P(
- VectorTypeConstants, AggressiveEliminateDeadConstantTest,
- ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
- // clang-format off
- // Tests eliminating dead constant type ivec2. One dead constant vector
- // and one used constant vector, each built from its own group of
- // scalar constants.
- {
- /* .used_consts = */
- {
- "%used_int_x = OpConstant %int 1",
- "%used_int_y = OpConstant %int 2",
- "%used_v2int = OpConstantComposite %v2int %used_int_x %used_int_y",
- },
- /* .main_insts = */
- {
- "%v2int_var = OpVariable %_pf_v2int Output",
- "OpStore %v2int_var %used_v2int",
- },
- /* .dead_consts = */
- {
- "%dead_int_x = OpConstant %int 1",
- "%dead_int_y = OpConstant %int 2",
- "%dead_v2int = OpConstantComposite %v2int %dead_int_x %dead_int_y",
- },
- /* .checks = */
- {
- "; CHECK: [[constx:%\\w+]] = OpConstant %int 1",
- "; CHECK: [[consty:%\\w+]] = OpConstant %int 2",
- "; CHECK: [[const:%\\w+]] = OpConstantComposite %v2int [[constx]] [[consty]]",
- "; CHECK-NOT: OpConstant",
- "; CHECK: OpStore {{%\\w+}} [[const]]",
- },
- },
- // Tests eliminating dead constant ivec3. One dead constant vector and
- // one used constant vector. But both built from a same group of
- // scalar constants.
- {
- /* .used_consts = */
- {
- "%used_int_x = OpConstant %int 1",
- "%used_int_y = OpConstant %int 2",
- "%used_int_z = OpConstant %int 3",
- "%used_v3int = OpConstantComposite %v3int %used_int_x %used_int_y %used_int_z",
- },
- /* .main_insts = */
- {
- "%v3int_var = OpVariable %_pf_v3int Output",
- "OpStore %v3int_var %used_v3int",
- },
- /* .dead_consts = */
- {
- "%dead_v3int = OpConstantComposite %v3int %used_int_x %used_int_y %used_int_z",
- },
- /* .checks = */
- {
- "; CHECK: [[constx:%\\w+]] = OpConstant %int 1",
- "; CHECK: [[consty:%\\w+]] = OpConstant %int 2",
- "; CHECK: [[constz:%\\w+]] = OpConstant %int 3",
- "; CHECK: [[const:%\\w+]] = OpConstantComposite %v3int [[constx]] [[consty]] [[constz]]",
- "; CHECK-NOT: OpConstant",
- "; CHECK: OpStore {{%\\w+}} [[const]]",
- },
- },
- // Tests eliminating dead constant vec2. One dead constant vector and
- // one used constant vector. Each built from its own group of scalar
- // constants.
- {
- /* .used_consts = */
- {
- "%used_float_x = OpConstant %float 3.1415",
- "%used_float_y = OpConstant %float 4.13",
- "%used_v2float = OpConstantComposite %v2float %used_float_x %used_float_y",
- },
- /* .main_insts = */
- {
- "%v2float_var = OpVariable %_pf_v2float Output",
- "OpStore %v2float_var %used_v2float",
- },
- /* .dead_consts = */
- {
- "%dead_float_x = OpConstant %float 3.1415",
- "%dead_float_y = OpConstant %float 4.13",
- "%dead_v2float = OpConstantComposite %v2float %dead_float_x %dead_float_y",
- },
- /* .checks = */
- {
- "; CHECK: [[constx:%\\w+]] = OpConstant %float 3.1415",
- "; CHECK: [[consty:%\\w+]] = OpConstant %float 4.13",
- "; CHECK: [[const:%\\w+]] = OpConstantComposite %v2float [[constx]] [[consty]]",
- "; CHECK-NOT: OpConstant",
- "; CHECK: OpStore {{%\\w+}} [[const]]",
- },
- },
- // Tests eliminating dead constant vec3. One dead constant vector and
- // one used constant vector. Both built from a same group of scalar
- // constants.
- {
- /* .used_consts = */
- {
- "%used_float_x = OpConstant %float 3.1415",
- "%used_float_y = OpConstant %float 4.25",
- "%used_float_z = OpConstant %float 4.75",
- "%used_v3float = OpConstantComposite %v3float %used_float_x %used_float_y %used_float_z",
- },
- /* .main_insts = */
- {
- "%v3float_var = OpVariable %_pf_v3float Output",
- "OpStore %v3float_var %used_v3float",
- },
- /* .dead_consts = */
- {
- "%dead_v3float = OpConstantComposite %v3float %used_float_x %used_float_y %used_float_z",
- },
- /* .checks = */
- {
- "; CHECK: [[constx:%\\w+]] = OpConstant %float 3.1415",
- "; CHECK: [[consty:%\\w+]] = OpConstant %float 4.25",
- "; CHECK: [[constz:%\\w+]] = OpConstant %float 4.75",
- "; CHECK: [[const:%\\w+]] = OpConstantComposite %v3float [[constx]] [[consty]]",
- "; CHECK-NOT: OpConstant",
- "; CHECK: OpStore {{%\\w+}} [[const]]",
- },
- },
- // clang-format on
- })));
- INSTANTIATE_TEST_SUITE_P(
- StructTypeConstants, AggressiveEliminateDeadConstantTest,
- ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
- // clang-format off
- // A plain struct type dead constants. All of its components are dead
- // constants too.
- {
- /* .used_consts = */ {},
- /* .main_insts = */ {},
- /* .dead_consts = */
- {
- "%dead_bool = OpConstantTrue %bool",
- "%dead_int = OpConstant %int 1",
- "%dead_float = OpConstant %float 2.5",
- "%dead_double = OpConstant %double 3.14159265358979",
- "%dead_struct = OpConstantComposite %flat_struct %dead_bool %dead_int %dead_float %dead_double",
- },
- /* .checks = */
- {
- "; CHECK-NOT: OpConstant",
- },
- },
- // A plain struct type dead constants. Some of its components are dead
- // constants while others are not.
- {
- /* .used_consts = */
- {
- "%used_int = OpConstant %int 1",
- "%used_double = OpConstant %double 3.14159265358979",
- },
- /* .main_insts = */
- {
- "%int_var = OpVariable %_pf_int Output",
- "OpStore %int_var %used_int",
- "%double_var = OpVariable %_pf_double Output",
- "OpStore %double_var %used_double",
- },
- /* .dead_consts = */
- {
- "%dead_bool = OpConstantTrue %bool",
- "%dead_float = OpConstant %float 2.5",
- "%dead_struct = OpConstantComposite %flat_struct %dead_bool %used_int %dead_float %used_double",
- },
- /* .checks = */
- {
- "; CHECK: [[int:%\\w+]] = OpConstant %int 1",
- "; CHECK: [[double:%\\w+]] = OpConstant %double 3.14159265358979",
- "; CHECK-NOT: OpConstant",
- "; CHECK: OpStore {{%\\w+}} [[int]]",
- "; CHECK: OpStore {{%\\w+}} [[double]]",
- },
- },
- // A nesting struct type dead constants. All components of both outer
- // and inner structs are dead and should be removed after dead constant
- // elimination.
- {
- /* .used_consts = */ {},
- /* .main_insts = */ {},
- /* .dead_consts = */
- {
- "%dead_bool = OpConstantTrue %bool",
- "%dead_int = OpConstant %int 1",
- "%dead_float = OpConstant %float 2.5",
- "%dead_double = OpConstant %double 3.1415926535",
- "%dead_inner_struct = OpConstantComposite %inner_struct %dead_bool %dead_int %dead_float %dead_double",
- "%dead_int2 = OpConstant %int 2",
- "%dead_double2 = OpConstant %double 1.428571428514",
- "%dead_outer_struct = OpConstantComposite %outer_struct %dead_inner_struct %dead_int2 %dead_double2",
- },
- /* .checks = */
- {
- "; CHECK-NOT: OpConstant",
- },
- },
- // A nesting struct type dead constants. Some of its components are
- // dead constants while others are not.
- {
- /* .used_consts = */
- {
- "%used_int = OpConstant %int 1",
- "%used_double = OpConstant %double 3.14159265358979",
- },
- /* .main_insts = */
- {
- "%int_var = OpVariable %_pf_int Output",
- "OpStore %int_var %used_int",
- "%double_var = OpVariable %_pf_double Output",
- "OpStore %double_var %used_double",
- },
- /* .dead_consts = */
- {
- "%dead_bool = OpConstantTrue %bool",
- "%dead_float = OpConstant %float 2.5",
- "%dead_inner_struct = OpConstantComposite %inner_struct %dead_bool %used_int %dead_float %used_double",
- "%dead_int = OpConstant %int 2",
- "%dead_outer_struct = OpConstantComposite %outer_struct %dead_inner_struct %dead_int %used_double",
- },
- /* .checks = */
- {
- "; CHECK: [[int:%\\w+]] = OpConstant %int 1",
- "; CHECK: [[double:%\\w+]] = OpConstant %double 3.14159265358979",
- "; CHECK-NOT: OpConstant",
- "; CHECK: OpStore {{%\\w+}} [[int]]",
- "; CHECK: OpStore {{%\\w+}} [[double]]",
- },
- },
- // A nesting struct case. The inner struct is used while the outer struct is not
- {
- /* .used_const = */
- {
- "%used_bool = OpConstantTrue %bool",
- "%used_int = OpConstant %int 1",
- "%used_float = OpConstant %float 1.23",
- "%used_double = OpConstant %double 1.2345678901234",
- "%used_inner_struct = OpConstantComposite %inner_struct %used_bool %used_int %used_float %used_double",
- },
- /* .main_insts = */
- {
- "%bool_var = OpVariable %_pf_bool Output",
- "%bool_from_inner_struct = OpCompositeExtract %bool %used_inner_struct 0",
- "OpStore %bool_var %bool_from_inner_struct",
- },
- /* .dead_consts = */
- {
- "%dead_int = OpConstant %int 2",
- "%dead_outer_struct = OpConstantComposite %outer_struct %used_inner_struct %dead_int %used_double"
- },
- /* .checks = */
- {
- "; CHECK: [[bool:%\\w+]] = OpConstantTrue",
- "; CHECK: [[int:%\\w+]] = OpConstant %int 1",
- "; CHECK: [[float:%\\w+]] = OpConstant %float 1.23",
- "; CHECK: [[double:%\\w+]] = OpConstant %double 1.2345678901234",
- "; CHECK: [[struct:%\\w+]] = OpConstantComposite %inner_struct [[bool]] [[int]] [[float]] [[double]]",
- "; CHECK-NOT: OpConstant",
- "; CHECK: OpCompositeExtract %bool [[struct]]",
- }
- },
- // A nesting struct case. The outer struct is used, so the inner struct should not
- // be removed even though it is not used anywhere.
- {
- /* .used_const = */
- {
- "%used_bool = OpConstantTrue %bool",
- "%used_int = OpConstant %int 1",
- "%used_float = OpConstant %float 1.23",
- "%used_double = OpConstant %double 1.2345678901234",
- "%used_inner_struct = OpConstantComposite %inner_struct %used_bool %used_int %used_float %used_double",
- "%used_outer_struct = OpConstantComposite %outer_struct %used_inner_struct %used_int %used_double"
- },
- /* .main_insts = */
- {
- "%int_var = OpVariable %_pf_int Output",
- "%int_from_outer_struct = OpCompositeExtract %int %used_outer_struct 1",
- "OpStore %int_var %int_from_outer_struct",
- },
- /* .dead_consts = */ {},
- /* .checks = */
- {
- "; CHECK: [[bool:%\\w+]] = OpConstantTrue %bool",
- "; CHECK: [[int:%\\w+]] = OpConstant %int 1",
- "; CHECK: [[float:%\\w+]] = OpConstant %float 1.23",
- "; CHECK: [[double:%\\w+]] = OpConstant %double 1.2345678901234",
- "; CHECK: [[inner_struct:%\\w+]] = OpConstantComposite %inner_struct %used_bool %used_int %used_float %used_double",
- "; CHECK: [[outer_struct:%\\w+]] = OpConstantComposite %outer_struct %used_inner_struct %used_int %used_double",
- "; CHECK: OpCompositeExtract %int [[outer_struct]]",
- },
- },
- // clang-format on
- })));
- INSTANTIATE_TEST_SUITE_P(
- ScalarTypeSpecConstants, AggressiveEliminateDeadConstantTest,
- ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
- // clang-format off
- // All scalar type spec constants.
- {
- /* .used_consts = */
- {
- "%used_bool = OpSpecConstantTrue %bool",
- "%used_uint = OpSpecConstant %uint 2",
- "%used_int = OpSpecConstant %int 2",
- "%used_float = OpSpecConstant %float 2.5",
- "%used_double = OpSpecConstant %double 1.428571428514",
- },
- /* .main_insts = */
- {
- "%bool_var = OpVariable %_pf_bool Output",
- "%uint_var = OpVariable %_pf_uint Output",
- "%int_var = OpVariable %_pf_int Output",
- "%float_var = OpVariable %_pf_float Output",
- "%double_var = OpVariable %_pf_double Output",
- "OpStore %bool_var %used_bool",
- "OpStore %uint_var %used_uint",
- "OpStore %int_var %used_int",
- "OpStore %float_var %used_float",
- "OpStore %double_var %used_double",
- },
- /* .dead_consts = */
- {
- "%dead_bool = OpSpecConstantTrue %bool",
- "%dead_uint = OpSpecConstant %uint 2",
- "%dead_int = OpSpecConstant %int 2",
- "%dead_float = OpSpecConstant %float 2.5",
- "%dead_double = OpSpecConstant %double 1.428571428514",
- },
- /* .checks = */
- {
- "; CHECK: [[bool:%\\w+]] = OpSpecConstantTrue %bool",
- "; CHECK: [[uint:%\\w+]] = OpSpecConstant %uint 2",
- "; CHECK: [[int:%\\w+]] = OpSpecConstant %int 2",
- "; CHECK: [[float:%\\w+]] = OpSpecConstant %float 2.5",
- "; CHECK: [[double:%\\w+]] = OpSpecConstant %double 1.428571428514",
- "; CHECK-NOT: OpSpecConstant",
- "; CHECK: OpStore {{%\\w+}} [[bool]]",
- "; CHECK: OpStore {{%\\w+}} [[uint]]",
- "; CHECK: OpStore {{%\\w+}} [[int]]",
- "; CHECK: OpStore {{%\\w+}} [[float]]",
- "; CHECK: OpStore {{%\\w+}} [[double]]",
- },
- },
- // clang-format on
- })));
- INSTANTIATE_TEST_SUITE_P(
- VectorTypeSpecConstants, AggressiveEliminateDeadConstantTest,
- ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
- // clang-format off
- // Bool vector type spec constants. One vector has all component dead,
- // another vector has one dead boolean and one used boolean.
- {
- /* .used_consts = */
- {
- "%used_bool = OpSpecConstantTrue %bool",
- },
- /* .main_insts = */
- {
- "%bool_var = OpVariable %_pf_bool Output",
- "OpStore %bool_var %used_bool",
- },
- /* .dead_consts = */
- {
- "%dead_bool = OpSpecConstantFalse %bool",
- "%dead_bool_vec1 = OpSpecConstantComposite %v2bool %dead_bool %dead_bool",
- "%dead_bool_vec2 = OpSpecConstantComposite %v2bool %dead_bool %used_bool",
- },
- /* .checks = */
- {
- "; CHECK: [[bool:%\\w+]] = OpSpecConstantTrue %bool",
- "; CHECK-NOT: OpSpecConstant",
- "; CHECK: OpStore {{%\\w+}} [[bool]]",
- },
- },
- // Uint vector type spec constants. One vector has all component dead,
- // another vector has one dead unsigned integer and one used unsigned
- // integer.
- {
- /* .used_consts = */
- {
- "%used_uint = OpSpecConstant %uint 3",
- },
- /* .main_insts = */
- {
- "%uint_var = OpVariable %_pf_uint Output",
- "OpStore %uint_var %used_uint",
- },
- /* .dead_consts = */
- {
- "%dead_uint = OpSpecConstant %uint 1",
- "%dead_uint_vec1 = OpSpecConstantComposite %v2uint %dead_uint %dead_uint",
- "%dead_uint_vec2 = OpSpecConstantComposite %v2uint %dead_uint %used_uint",
- },
- /* .checks = */
- {
- "; CHECK: [[uint:%\\w+]] = OpSpecConstant %uint 3",
- "; CHECK-NOT: OpSpecConstant",
- "; CHECK: OpStore {{%\\w+}} [[uint]]",
- },
- },
- // Int vector type spec constants. One vector has all component dead,
- // another vector has one dead integer and one used integer.
- {
- /* .used_consts = */
- {
- "%used_int = OpSpecConstant %int 3",
- },
- /* .main_insts = */
- {
- "%int_var = OpVariable %_pf_int Output",
- "OpStore %int_var %used_int",
- },
- /* .dead_consts = */
- {
- "%dead_int = OpSpecConstant %int 1",
- "%dead_int_vec1 = OpSpecConstantComposite %v2int %dead_int %dead_int",
- "%dead_int_vec2 = OpSpecConstantComposite %v2int %dead_int %used_int",
- },
- /* .checks = */
- {
- "; CHECK: [[int:%\\w+]] = OpSpecConstant %int 3",
- "; CHECK-NOT: OpSpecConstant",
- "; CHECK: OpStore {{%\\w+}} [[int]]",
- },
- },
- // Int vector type spec constants built with both spec constants and
- // front-end constants.
- {
- /* .used_consts = */
- {
- "%used_spec_int = OpSpecConstant %int 3",
- "%used_front_end_int = OpConstant %int 3",
- },
- /* .main_insts = */
- {
- "%int_var1 = OpVariable %_pf_int Output",
- "OpStore %int_var1 %used_spec_int",
- "%int_var2 = OpVariable %_pf_int Output",
- "OpStore %int_var2 %used_front_end_int",
- },
- /* .dead_consts = */
- {
- "%dead_spec_int = OpSpecConstant %int 1",
- "%dead_front_end_int = OpConstant %int 1",
- // Dead front-end and dead spec constants
- "%dead_int_vec1 = OpSpecConstantComposite %v2int %dead_spec_int %dead_front_end_int",
- // Used front-end and dead spec constants
- "%dead_int_vec2 = OpSpecConstantComposite %v2int %dead_spec_int %used_front_end_int",
- // Dead front-end and used spec constants
- "%dead_int_vec3 = OpSpecConstantComposite %v2int %dead_front_end_int %used_spec_int",
- },
- /* .checks = */
- {
- "; CHECK: [[int1:%\\w+]] = OpSpecConstant %int 3",
- "; CHECK: [[int2:%\\w+]] = OpConstant %int 3",
- "; CHECK-NOT: OpSpecConstant",
- "; CHECK-NOT: OpConstant",
- "; CHECK: OpStore {{%\\w+}} [[int1]]",
- "; CHECK: OpStore {{%\\w+}} [[int2]]",
- },
- },
- // clang-format on
- })));
- INSTANTIATE_TEST_SUITE_P(
- SpecConstantOp, AggressiveEliminateDeadConstantTest,
- ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
- // clang-format off
- // Cast operations: uint <-> int <-> bool
- {
- /* .used_consts = */ {},
- /* .main_insts = */ {},
- /* .dead_consts = */
- {
- // Assistant constants, only used in dead spec constant
- // operations.
- "%signed_zero = OpConstant %int 0",
- "%signed_zero_vec = OpConstantComposite %v2int %signed_zero %signed_zero",
- "%unsigned_zero = OpConstant %uint 0",
- "%unsigned_zero_vec = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero",
- "%signed_one = OpConstant %int 1",
- "%signed_one_vec = OpConstantComposite %v2int %signed_one %signed_one",
- "%unsigned_one = OpConstant %uint 1",
- "%unsigned_one_vec = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
- // Spec constants that support casting to each other.
- "%dead_bool = OpSpecConstantTrue %bool",
- "%dead_uint = OpSpecConstant %uint 1",
- "%dead_int = OpSpecConstant %int 2",
- "%dead_bool_vec = OpSpecConstantComposite %v2bool %dead_bool %dead_bool",
- "%dead_uint_vec = OpSpecConstantComposite %v2uint %dead_uint %dead_uint",
- "%dead_int_vec = OpSpecConstantComposite %v2int %dead_int %dead_int",
- // Scalar cast to boolean spec constant.
- "%int_to_bool = OpSpecConstantOp %bool INotEqual %dead_int %signed_zero",
- "%uint_to_bool = OpSpecConstantOp %bool INotEqual %dead_uint %unsigned_zero",
- // Vector cast to boolean spec constant.
- "%int_to_bool_vec = OpSpecConstantOp %v2bool INotEqual %dead_int_vec %signed_zero_vec",
- "%uint_to_bool_vec = OpSpecConstantOp %v2bool INotEqual %dead_uint_vec %unsigned_zero_vec",
- // Scalar cast to int spec constant.
- "%bool_to_int = OpSpecConstantOp %int Select %dead_bool %signed_one %signed_zero",
- "%uint_to_int = OpSpecConstantOp %uint IAdd %dead_uint %unsigned_zero",
- // Vector cast to int spec constant.
- "%bool_to_int_vec = OpSpecConstantOp %v2int Select %dead_bool_vec %signed_one_vec %signed_zero_vec",
- "%uint_to_int_vec = OpSpecConstantOp %v2uint IAdd %dead_uint_vec %unsigned_zero_vec",
- // Scalar cast to uint spec constant.
- "%bool_to_uint = OpSpecConstantOp %uint Select %dead_bool %unsigned_one %unsigned_zero",
- "%int_to_uint_vec = OpSpecConstantOp %uint IAdd %dead_int %signed_zero",
- // Vector cast to uint spec constant.
- "%bool_to_uint_vec = OpSpecConstantOp %v2uint Select %dead_bool_vec %unsigned_one_vec %unsigned_zero_vec",
- "%int_to_uint = OpSpecConstantOp %v2uint IAdd %dead_int_vec %signed_zero_vec",
- },
- /* .checks = */
- {
- "; CHECK-NOT: OpConstant",
- "; CHECK-NOT: OpSpecConstant",
- },
- },
- // Add, sub, mul, div, rem.
- {
- /* .used_consts = */ {},
- /* .main_insts = */ {},
- /* .dead_consts = */
- {
- "%dead_spec_int_a = OpSpecConstant %int 1",
- "%dead_spec_int_a_vec = OpSpecConstantComposite %v2int %dead_spec_int_a %dead_spec_int_a",
- "%dead_spec_int_b = OpSpecConstant %int 2",
- "%dead_spec_int_b_vec = OpSpecConstantComposite %v2int %dead_spec_int_b %dead_spec_int_b",
- "%dead_const_int_c = OpConstant %int 3",
- "%dead_const_int_c_vec = OpConstantComposite %v2int %dead_const_int_c %dead_const_int_c",
- // Add
- "%add_a_b = OpSpecConstantOp %int IAdd %dead_spec_int_a %dead_spec_int_b",
- "%add_a_b_vec = OpSpecConstantOp %v2int IAdd %dead_spec_int_a_vec %dead_spec_int_b_vec",
- // Sub
- "%sub_a_b = OpSpecConstantOp %int ISub %dead_spec_int_a %dead_spec_int_b",
- "%sub_a_b_vec = OpSpecConstantOp %v2int ISub %dead_spec_int_a_vec %dead_spec_int_b_vec",
- // Mul
- "%mul_a_b = OpSpecConstantOp %int IMul %dead_spec_int_a %dead_spec_int_b",
- "%mul_a_b_vec = OpSpecConstantOp %v2int IMul %dead_spec_int_a_vec %dead_spec_int_b_vec",
- // Div
- "%div_a_b = OpSpecConstantOp %int SDiv %dead_spec_int_a %dead_spec_int_b",
- "%div_a_b_vec = OpSpecConstantOp %v2int SDiv %dead_spec_int_a_vec %dead_spec_int_b_vec",
- // Bitwise Xor
- "%xor_a_b = OpSpecConstantOp %int BitwiseXor %dead_spec_int_a %dead_spec_int_b",
- "%xor_a_b_vec = OpSpecConstantOp %v2int BitwiseXor %dead_spec_int_a_vec %dead_spec_int_b_vec",
- // Scalar Comparison
- "%less_a_b = OpSpecConstantOp %bool SLessThan %dead_spec_int_a %dead_spec_int_b",
- },
- /* .checks = */
- {
- "; CHECK-NOT: OpConstant",
- "; CHECK-NOT: OpSpecConstant",
- },
- },
- // Vectors without used swizzles should be removed.
- {
- /* .used_consts = */
- {
- "%used_int = OpConstant %int 3",
- },
- /* .main_insts = */
- {
- "%int_var = OpVariable %_pf_int Output",
- "OpStore %int_var %used_int",
- },
- /* .dead_consts = */
- {
- "%dead_int = OpConstant %int 3",
- "%dead_spec_int_a = OpSpecConstant %int 1",
- "%vec_a = OpSpecConstantComposite %v4int %dead_spec_int_a %dead_spec_int_a %dead_int %dead_int",
- "%dead_spec_int_b = OpSpecConstant %int 2",
- "%vec_b = OpSpecConstantComposite %v4int %dead_spec_int_b %dead_spec_int_b %used_int %used_int",
- // Extract scalar
- "%a_x = OpSpecConstantOp %int CompositeExtract %vec_a 0",
- "%b_x = OpSpecConstantOp %int CompositeExtract %vec_b 0",
- // Extract vector
- "%a_xy = OpSpecConstantOp %v2int VectorShuffle %vec_a %vec_a 0 1",
- "%b_xy = OpSpecConstantOp %v2int VectorShuffle %vec_b %vec_b 0 1",
- },
- /* .checks = */
- {
- "; CHECK: [[int:%\\w+]] = OpConstant %int 3",
- "; CHECK-NOT: OpConstant",
- "; CHECK-NOT: OpSpecConstant",
- "; CHECK: OpStore {{%\\w+}} [[int]]",
- },
- },
- // Vectors with used swizzles should not be removed.
- {
- /* .used_consts = */
- {
- "%used_int = OpConstant %int 3",
- "%used_spec_int_a = OpSpecConstant %int 1",
- "%used_spec_int_b = OpSpecConstant %int 2",
- // Create vectors
- "%vec_a = OpSpecConstantComposite %v4int %used_spec_int_a %used_spec_int_a %used_int %used_int",
- "%vec_b = OpSpecConstantComposite %v4int %used_spec_int_b %used_spec_int_b %used_int %used_int",
- // Extract vector
- "%a_xy = OpSpecConstantOp %v2int VectorShuffle %vec_a %vec_a 0 1",
- "%b_xy = OpSpecConstantOp %v2int VectorShuffle %vec_b %vec_b 0 1",
- },
- /* .main_insts = */
- {
- "%v2int_var_a = OpVariable %_pf_v2int Output",
- "%v2int_var_b = OpVariable %_pf_v2int Output",
- "OpStore %v2int_var_a %a_xy",
- "OpStore %v2int_var_b %b_xy",
- },
- /* .dead_consts = */ {},
- /* .checks = */
- {
- "; CHECK: [[int:%\\w+]] = OpConstant %int 3",
- "; CHECK: [[a:%\\w+]] = OpSpecConstant %int 1",
- "; CHECK: [[b:%\\w+]] = OpSpecConstant %int 2",
- "; CHECK: [[veca:%\\w+]] = OpSpecConstantComposite %v4int [[a]] [[a]] [[int]] [[int]]",
- "; CHECK: [[vecb:%\\w+]] = OpSpecConstantComposite %v4int [[b]] [[b]] [[int]] [[int]]",
- "; CHECK: [[exa:%\\w+]] = OpSpecConstantOp %v2int VectorShuffle [[veca]] [[veca]] 0 1",
- "; CHECK: [[exb:%\\w+]] = OpSpecConstantOp %v2int VectorShuffle [[vecb]] [[vecb]] 0 1",
- "; CHECK-NOT: OpConstant",
- "; CHECK-NOT: OpSpecConstant",
- "; CHECK: OpStore {{%\\w+}} [[exa]]",
- "; CHECK: OpStore {{%\\w+}} [[exb]]",
- },
- },
- // clang-format on
- })));
- INSTANTIATE_TEST_SUITE_P(
- LongDefUseChain, AggressiveEliminateDeadConstantTest,
- ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
- // clang-format off
- // Long Def-Use chain with binary operations.
- {
- /* .used_consts = */
- {
- "%array_size = OpConstant %int 4",
- "%type_arr_int_4 = OpTypeArray %int %array_size",
- "%used_int_0 = OpConstant %int 100",
- "%used_int_1 = OpConstant %int 1",
- "%used_int_2 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_1",
- "%used_int_3 = OpSpecConstantOp %int ISub %used_int_0 %used_int_2",
- "%used_int_4 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_3",
- "%used_int_5 = OpSpecConstantOp %int ISub %used_int_0 %used_int_4",
- "%used_int_6 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_5",
- "%used_int_7 = OpSpecConstantOp %int ISub %used_int_0 %used_int_6",
- "%used_int_8 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_7",
- "%used_int_9 = OpSpecConstantOp %int ISub %used_int_0 %used_int_8",
- "%used_int_10 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_9",
- "%used_int_11 = OpSpecConstantOp %int ISub %used_int_0 %used_int_10",
- "%used_int_12 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_11",
- "%used_int_13 = OpSpecConstantOp %int ISub %used_int_0 %used_int_12",
- "%used_int_14 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_13",
- "%used_int_15 = OpSpecConstantOp %int ISub %used_int_0 %used_int_14",
- "%used_int_16 = OpSpecConstantOp %int ISub %used_int_0 %used_int_15",
- "%used_int_17 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_16",
- "%used_int_18 = OpSpecConstantOp %int ISub %used_int_0 %used_int_17",
- "%used_int_19 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_18",
- "%used_int_20 = OpSpecConstantOp %int ISub %used_int_0 %used_int_19",
- "%used_vec_a = OpSpecConstantComposite %v2int %used_int_18 %used_int_19",
- "%used_vec_b = OpSpecConstantOp %v2int IMul %used_vec_a %used_vec_a",
- "%used_int_21 = OpSpecConstantOp %int CompositeExtract %used_vec_b 0",
- "%used_array = OpConstantComposite %type_arr_int_4 %used_int_20 %used_int_20 %used_int_21 %used_int_21",
- },
- /* .main_insts = */
- {
- "%int_var = OpVariable %_pf_int Output",
- "%used_array_2 = OpCompositeExtract %int %used_array 2",
- "OpStore %int_var %used_array_2",
- },
- /* .dead_consts = */
- {
- "%dead_int_1 = OpConstant %int 2",
- "%dead_int_2 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_1",
- "%dead_int_3 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_2",
- "%dead_int_4 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_3",
- "%dead_int_5 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_4",
- "%dead_int_6 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_5",
- "%dead_int_7 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_6",
- "%dead_int_8 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_7",
- "%dead_int_9 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_8",
- "%dead_int_10 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_9",
- "%dead_int_11 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_10",
- "%dead_int_12 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_11",
- "%dead_int_13 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_12",
- "%dead_int_14 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_13",
- "%dead_int_15 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_14",
- "%dead_int_16 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_15",
- "%dead_int_17 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_16",
- "%dead_int_18 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_17",
- "%dead_int_19 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_18",
- "%dead_int_20 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_19",
- "%dead_vec_a = OpSpecConstantComposite %v2int %dead_int_18 %dead_int_19",
- "%dead_vec_b = OpSpecConstantOp %v2int IMul %dead_vec_a %dead_vec_a",
- "%dead_int_21 = OpSpecConstantOp %int CompositeExtract %dead_vec_b 0",
- "%dead_array = OpConstantComposite %type_arr_int_4 %dead_int_20 %used_int_20 %dead_int_19 %used_int_19",
- },
- /* .checks = */
- {
- "; CHECK: OpConstant %int 4",
- "; CHECK: [[array:%\\w+]] = OpConstantComposite %type_arr_int_4 %used_int_20 %used_int_20 %used_int_21 %used_int_21",
- "; CHECK-NOT: OpConstant",
- "; CHECK-NOT: OpSpecConstant",
- "; CHECK: OpStore {{%\\w+}} [[array]]",
- },
- },
- // Long Def-Use chain with swizzle
- // clang-format on
- })));
- TEST_F(AggressiveDCETest, DeadDecorationGroup) {
- // The decoration group should be eliminated because the target of group
- // decorate is dead.
- const std::string text = R"(
- ; CHECK-NOT: OpDecorat
- ; CHECK-NOT: OpGroupDecorate
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %1 Restrict
- OpDecorate %1 Aliased
- %1 = OpDecorationGroup
- OpGroupDecorate %1 %var
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %uint_ptr = OpTypePointer Function %uint
- %main = OpFunction %void None %func
- %2 = OpLabel
- %var = OpVariable %uint_ptr Function
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, DeadDecorationGroupAndValidDecorationMgr) {
- // The decoration group should be eliminated because the target of group
- // decorate is dead.
- const std::string text = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %1 Restrict
- OpDecorate %1 Aliased
- %1 = OpDecorationGroup
- OpGroupDecorate %1 %var
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %uint_ptr = OpTypePointer Function %uint
- %main = OpFunction %void None %func
- %2 = OpLabel
- %var = OpVariable %uint_ptr Function
- OpReturn
- OpFunctionEnd
- )";
- auto pass = MakeUnique<AggressiveDCEPass>();
- auto consumer = [](spv_message_level_t, const char*, const spv_position_t&,
- const char* message) {
- std::cerr << message << std::endl;
- };
- auto context = BuildModule(SPV_ENV_UNIVERSAL_1_1, consumer, text);
- // Build the decoration manager before the pass.
- context->get_decoration_mgr();
- const auto status = pass->Run(context.get());
- EXPECT_EQ(status, Pass::Status::SuccessWithChange);
- }
- TEST_F(AggressiveDCETest, ParitallyDeadDecorationGroup) {
- const std::string text = R"(
- ; CHECK: OpDecorate [[grp:%\w+]] Restrict
- ; CHECK: [[grp]] = OpDecorationGroup
- ; CHECK: OpGroupDecorate [[grp]] [[output:%\w+]]
- ; CHECK: [[output]] = OpVariable {{%\w+}} Output
- ; CHECK-NOT: OpVariable {{%\w+}} Function
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %output
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %1 Restrict
- %1 = OpDecorationGroup
- OpGroupDecorate %1 %var %output
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %uint_ptr_Function = OpTypePointer Function %uint
- %uint_ptr_Output = OpTypePointer Output %uint
- %uint_0 = OpConstant %uint 0
- %output = OpVariable %uint_ptr_Output Output
- %main = OpFunction %void None %func
- %2 = OpLabel
- %var = OpVariable %uint_ptr_Function Function
- OpStore %output %uint_0
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, ParitallyDeadDecorationGroupDifferentGroupDecorate) {
- const std::string text = R"(
- ; CHECK: OpDecorate [[grp:%\w+]] Restrict
- ; CHECK: [[grp]] = OpDecorationGroup
- ; CHECK: OpGroupDecorate [[grp]] [[output:%\w+]]
- ; CHECK-NOT: OpGroupDecorate
- ; CHECK: [[output]] = OpVariable {{%\w+}} Output
- ; CHECK-NOT: OpVariable {{%\w+}} Function
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %output
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %1 Restrict
- %1 = OpDecorationGroup
- OpGroupDecorate %1 %output
- OpGroupDecorate %1 %var
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %uint_ptr_Function = OpTypePointer Function %uint
- %uint_ptr_Output = OpTypePointer Output %uint
- %uint_0 = OpConstant %uint 0
- %output = OpVariable %uint_ptr_Output Output
- %main = OpFunction %void None %func
- %2 = OpLabel
- %var = OpVariable %uint_ptr_Function Function
- OpStore %output %uint_0
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, DeadGroupMemberDecorate) {
- const std::string text = R"(
- ; CHECK-NOT: OpDec
- ; CHECK-NOT: OpGroup
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %1 Offset 0
- OpDecorate %1 Uniform
- %1 = OpDecorationGroup
- OpGroupMemberDecorate %1 %var 0
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %struct = OpTypeStruct %uint %uint
- %struct_ptr = OpTypePointer Function %struct
- %main = OpFunction %void None %func
- %2 = OpLabel
- %var = OpVariable %struct_ptr Function
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, PartiallyDeadGroupMemberDecorate) {
- const std::string text = R"(
- ; CHECK: OpDecorate [[grp:%\w+]] Offset 0
- ; CHECK: OpDecorate [[grp]] RelaxedPrecision
- ; CHECK: [[grp]] = OpDecorationGroup
- ; CHECK: OpGroupMemberDecorate [[grp]] [[output:%\w+]] 1
- ; CHECK: [[output]] = OpTypeStruct
- ; CHECK-NOT: OpTypeStruct
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %output
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %1 Offset 0
- OpDecorate %1 RelaxedPrecision
- %1 = OpDecorationGroup
- OpGroupMemberDecorate %1 %var_struct 0 %output_struct 1
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %var_struct = OpTypeStruct %uint %uint
- %output_struct = OpTypeStruct %uint %uint
- %struct_ptr_Function = OpTypePointer Function %var_struct
- %struct_ptr_Output = OpTypePointer Output %output_struct
- %uint_ptr_Output = OpTypePointer Output %uint
- %output = OpVariable %struct_ptr_Output Output
- %uint_0 = OpConstant %uint 0
- %main = OpFunction %void None %func
- %2 = OpLabel
- %var = OpVariable %struct_ptr_Function Function
- %3 = OpAccessChain %uint_ptr_Output %output %uint_0
- OpStore %3 %uint_0
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest,
- PartiallyDeadGroupMemberDecorateDifferentGroupDecorate) {
- const std::string text = R"(
- ; CHECK: OpDecorate [[grp:%\w+]] Offset 0
- ; CHECK: OpDecorate [[grp]] RelaxedPrecision
- ; CHECK: [[grp]] = OpDecorationGroup
- ; CHECK: OpGroupMemberDecorate [[grp]] [[output:%\w+]] 1
- ; CHECK-NOT: OpGroupMemberDecorate
- ; CHECK: [[output]] = OpTypeStruct
- ; CHECK-NOT: OpTypeStruct
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %output
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %1 Offset 0
- OpDecorate %1 RelaxedPrecision
- %1 = OpDecorationGroup
- OpGroupMemberDecorate %1 %var_struct 0
- OpGroupMemberDecorate %1 %output_struct 1
- %void = OpTypeVoid
- %func = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %var_struct = OpTypeStruct %uint %uint
- %output_struct = OpTypeStruct %uint %uint
- %struct_ptr_Function = OpTypePointer Function %var_struct
- %struct_ptr_Output = OpTypePointer Output %output_struct
- %uint_ptr_Output = OpTypePointer Output %uint
- %output = OpVariable %struct_ptr_Output Output
- %uint_0 = OpConstant %uint 0
- %main = OpFunction %void None %func
- %2 = OpLabel
- %var = OpVariable %struct_ptr_Function Function
- %3 = OpAccessChain %uint_ptr_Output %output %uint_0
- OpStore %3 %uint_0
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- // Test for #1404
- TEST_F(AggressiveDCETest, DontRemoveWorkgroupSize) {
- const std::string text = R"(
- ; CHECK: OpDecorate [[wgs:%\w+]] BuiltIn WorkgroupSize
- ; CHECK: [[wgs]] = OpSpecConstantComposite
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %func "func"
- OpExecutionMode %func LocalSize 1 1 1
- OpDecorate %1 BuiltIn WorkgroupSize
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %functy = OpTypeFunction %void
- %v3int = OpTypeVector %int 3
- %2 = OpSpecConstant %int 1
- %1 = OpSpecConstantComposite %v3int %2 %2 %2
- %func = OpFunction %void None %functy
- %3 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- // Test for #1214
- TEST_F(AggressiveDCETest, LoopHeaderIsAlsoAnotherLoopMerge) {
- const std::string text = R"(OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "func" %2
- OpExecutionMode %1 OriginUpperLeft
- %void = OpTypeVoid
- %bool = OpTypeBool
- %true = OpConstantTrue %bool
- %uint = OpTypeInt 32 0
- %_ptr_Output_uint = OpTypePointer Output %uint
- %2 = OpVariable %_ptr_Output_uint Output
- %uint_0 = OpConstant %uint 0
- %9 = OpTypeFunction %void
- %1 = OpFunction %void None %9
- %10 = OpLabel
- OpBranch %11
- %11 = OpLabel
- OpLoopMerge %12 %13 None
- OpBranchConditional %true %14 %13
- %14 = OpLabel
- OpStore %2 %uint_0
- OpLoopMerge %15 %16 None
- OpBranchConditional %true %15 %16
- %16 = OpLabel
- OpBranch %14
- %15 = OpLabel
- OpBranchConditional %true %12 %13
- %13 = OpLabel
- OpBranch %11
- %12 = OpLabel
- %17 = OpPhi %uint %uint_0 %15 %uint_0 %18
- OpStore %2 %17
- OpLoopMerge %19 %18 None
- OpBranchConditional %true %19 %18
- %18 = OpLabel
- OpBranch %12
- %19 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(text, text, true, true);
- }
- TEST_F(AggressiveDCETest, BreaksDontVisitPhis) {
- const std::string text = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %func "func" %var
- OpExecutionMode %func OriginUpperLeft
- %void = OpTypeVoid
- %bool = OpTypeBool
- %true = OpConstantTrue %bool
- %int = OpTypeInt 32 0
- %int_ptr_Output = OpTypePointer Output %int
- %var = OpVariable %int_ptr_Output Output
- %int0 = OpConstant %int 0
- %functy = OpTypeFunction %void
- %func = OpFunction %void None %functy
- %entry = OpLabel
- OpBranch %outer_header
- %outer_header = OpLabel
- OpLoopMerge %outer_merge %outer_continue None
- OpBranchConditional %true %inner_header %outer_continue
- %inner_header = OpLabel
- %phi = OpPhi %int %int0 %outer_header %int0 %inner_continue
- OpStore %var %phi
- OpLoopMerge %inner_merge %inner_continue None
- OpBranchConditional %true %inner_merge %inner_continue
- %inner_continue = OpLabel
- OpBranch %inner_header
- %inner_merge = OpLabel
- OpBranch %outer_continue
- %outer_continue = OpLabel
- %p = OpPhi %int %int0 %outer_header %int0 %inner_merge
- OpStore %var %p
- OpBranch %outer_header
- %outer_merge = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- EXPECT_EQ(Pass::Status::SuccessWithoutChange,
- std::get<1>(SinglePassRunAndDisassemble<AggressiveDCEPass>(
- text, false, true)));
- }
- // Test for #1212
- TEST_F(AggressiveDCETest, ConstStoreInnerLoop) {
- const std::string text = R"(OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "main" %2
- %void = OpTypeVoid
- %4 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %bool = OpTypeBool
- %true = OpConstantTrue %bool
- %_ptr_Output_float = OpTypePointer Output %float
- %2 = OpVariable %_ptr_Output_float Output
- %float_3 = OpConstant %float 3
- %1 = OpFunction %void None %4
- %13 = OpLabel
- OpBranch %14
- %14 = OpLabel
- OpLoopMerge %15 %16 None
- OpBranchConditional %true %17 %15
- %17 = OpLabel
- OpStore %2 %float_3
- OpLoopMerge %18 %17 None
- OpBranchConditional %true %18 %17
- %18 = OpLabel
- OpBranch %15
- %16 = OpLabel
- OpBranch %14
- %15 = OpLabel
- OpBranch %20
- %20 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(text, text, true, true);
- }
- // Test for #1212
- TEST_F(AggressiveDCETest, InnerLoopCopy) {
- const std::string text = R"(OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %1 "main" %2 %3
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %bool = OpTypeBool
- %true = OpConstantTrue %bool
- %_ptr_Output_float = OpTypePointer Output %float
- %_ptr_Input_float = OpTypePointer Input %float
- %2 = OpVariable %_ptr_Output_float Output
- %3 = OpVariable %_ptr_Input_float Input
- %1 = OpFunction %void None %5
- %14 = OpLabel
- OpBranch %15
- %15 = OpLabel
- OpLoopMerge %16 %17 None
- OpBranchConditional %true %18 %16
- %18 = OpLabel
- %19 = OpLoad %float %3
- OpStore %2 %19
- OpLoopMerge %20 %18 None
- OpBranchConditional %true %20 %18
- %20 = OpLabel
- OpBranch %16
- %17 = OpLabel
- OpBranch %15
- %16 = OpLabel
- OpBranch %22
- %22 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(text, text, true, true);
- }
- TEST_F(AggressiveDCETest, AtomicAdd) {
- const std::string text = R"(OpCapability SampledBuffer
- OpCapability StorageImageExtendedFormats
- OpCapability ImageBuffer
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %2 "min"
- OpExecutionMode %2 LocalSize 64 1 1
- OpSource HLSL 600
- OpDecorate %4 DescriptorSet 4
- OpDecorate %4 Binding 70
- %uint = OpTypeInt 32 0
- %6 = OpTypeImage %uint Buffer 0 0 0 2 R32ui
- %_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6
- %_ptr_Private_6 = OpTypePointer Private %6
- %void = OpTypeVoid
- %10 = OpTypeFunction %void
- %uint_0 = OpConstant %uint 0
- %uint_1 = OpConstant %uint 1
- %_ptr_Image_uint = OpTypePointer Image %uint
- %4 = OpVariable %_ptr_UniformConstant_6 UniformConstant
- %16 = OpVariable %_ptr_Private_6 Private
- %2 = OpFunction %void None %10
- %17 = OpLabel
- %18 = OpLoad %6 %4
- OpStore %16 %18
- %19 = OpImageTexelPointer %_ptr_Image_uint %16 %uint_0 %uint_0
- %20 = OpAtomicIAdd %uint %19 %uint_1 %uint_0 %uint_1
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(text, text, true, true);
- }
- TEST_F(AggressiveDCETest, SafelyRemoveDecorateString) {
- const std::string preamble = R"(OpCapability Shader
- OpExtension "SPV_GOOGLE_hlsl_functionality1"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main"
- OpExecutionMode %1 OriginUpperLeft
- )";
- const std::string body_before =
- R"(OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "FOOBAR"
- %void = OpTypeVoid
- %4 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
- %2 = OpVariable %_ptr_StorageBuffer_uint StorageBuffer
- %1 = OpFunction %void None %4
- %7 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- const std::string body_after = R"(%void = OpTypeVoid
- %4 = OpTypeFunction %void
- %1 = OpFunction %void None %4
- %7 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(preamble + body_before,
- preamble + body_after, true, true);
- }
- TEST_F(AggressiveDCETest, CopyMemoryToGlobal) {
- // |local| is loaded in an OpCopyMemory instruction. So the store must be
- // kept alive.
- const std::string test =
- R"(OpCapability Geometry
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %global
- OpExecutionMode %main Triangles
- OpExecutionMode %main Invocations 1
- OpExecutionMode %main OutputTriangleStrip
- OpExecutionMode %main OutputVertices 5
- OpSource GLSL 440
- OpName %main "main"
- OpName %local "local"
- OpName %global "global"
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %12 = OpConstantNull %v4float
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %global = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %7
- %19 = OpLabel
- %local = OpVariable %_ptr_Function_v4float Function
- OpStore %local %12
- OpCopyMemory %global %local
- OpEndPrimitive
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(test, test, true, true);
- }
- TEST_F(AggressiveDCETest, CopyMemoryToLocal) {
- // Make sure the store to |local2| using OpCopyMemory is kept and keeps
- // |local1| alive.
- const std::string test =
- R"(OpCapability Geometry
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %global
- OpExecutionMode %main Triangles
- OpExecutionMode %main Invocations 1
- OpExecutionMode %main OutputTriangleStrip
- OpExecutionMode %main OutputVertices 5
- OpSource GLSL 440
- OpName %main "main"
- OpName %local1 "local1"
- OpName %local2 "local2"
- OpName %global "global"
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %12 = OpConstantNull %v4float
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %global = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %7
- %19 = OpLabel
- %local1 = OpVariable %_ptr_Function_v4float Function
- %local2 = OpVariable %_ptr_Function_v4float Function
- OpStore %local1 %12
- OpCopyMemory %local2 %local1
- OpCopyMemory %global %local2
- OpEndPrimitive
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(test, test, true, true);
- }
- TEST_F(AggressiveDCETest, RemoveCopyMemoryToLocal) {
- // Test that we remove function scope variables that are stored to using
- // OpCopyMemory, but are never loaded. We can remove both |local1| and
- // |local2|.
- const std::string test =
- R"(OpCapability Geometry
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %global
- OpExecutionMode %main Triangles
- OpExecutionMode %main Invocations 1
- OpExecutionMode %main OutputTriangleStrip
- OpExecutionMode %main OutputVertices 5
- OpSource GLSL 440
- OpName %main "main"
- OpName %local1 "local1"
- OpName %local2 "local2"
- OpName %global "global"
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %12 = OpConstantNull %v4float
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %global = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %7
- %19 = OpLabel
- %local1 = OpVariable %_ptr_Function_v4float Function
- %local2 = OpVariable %_ptr_Function_v4float Function
- OpStore %local1 %12
- OpCopyMemory %local2 %local1
- OpEndPrimitive
- OpReturn
- OpFunctionEnd
- )";
- const std::string result =
- R"(OpCapability Geometry
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %global
- OpExecutionMode %main Triangles
- OpExecutionMode %main Invocations 1
- OpExecutionMode %main OutputTriangleStrip
- OpExecutionMode %main OutputVertices 5
- OpSource GLSL 440
- OpName %main "main"
- OpName %global "global"
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %global = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %7
- %19 = OpLabel
- OpEndPrimitive
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(test, result, true, true);
- }
- TEST_F(AggressiveDCETest, RemoveCopyMemoryToLocal2) {
- // We are able to remove "local2" because it is not loaded, but have to keep
- // the stores to "local1".
- const std::string test =
- R"(OpCapability Geometry
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %global
- OpExecutionMode %main Triangles
- OpExecutionMode %main Invocations 1
- OpExecutionMode %main OutputTriangleStrip
- OpExecutionMode %main OutputVertices 5
- OpSource GLSL 440
- OpName %main "main"
- OpName %local1 "local1"
- OpName %local2 "local2"
- OpName %global "global"
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %12 = OpConstantNull %v4float
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %global = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %7
- %19 = OpLabel
- %local1 = OpVariable %_ptr_Function_v4float Function
- %local2 = OpVariable %_ptr_Function_v4float Function
- OpStore %local1 %12
- OpCopyMemory %local2 %local1
- OpCopyMemory %global %local1
- OpEndPrimitive
- OpReturn
- OpFunctionEnd
- )";
- const std::string result =
- R"(OpCapability Geometry
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Geometry %main "main" %global
- OpExecutionMode %main Triangles
- OpExecutionMode %main Invocations 1
- OpExecutionMode %main OutputTriangleStrip
- OpExecutionMode %main OutputVertices 5
- OpSource GLSL 440
- OpName %main "main"
- OpName %local1 "local1"
- OpName %global "global"
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %12 = OpConstantNull %v4float
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %global = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %7
- %19 = OpLabel
- %local1 = OpVariable %_ptr_Function_v4float Function
- OpStore %local1 %12
- OpCopyMemory %global %local1
- OpEndPrimitive
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(test, result, true, true);
- }
- TEST_F(AggressiveDCETest, StructuredIfWithConditionalExit) {
- // We are able to remove "local2" because it is not loaded, but have to keep
- // the stores to "local1".
- const std::string test =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
- OpSourceExtension "GL_GOOGLE_include_directive"
- OpName %main "main"
- OpName %a "a"
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_Uniform_int = OpTypePointer Uniform %int
- %int_0 = OpConstant %int 0
- %bool = OpTypeBool
- %int_100 = OpConstant %int 100
- %int_1 = OpConstant %int 1
- %a = OpVariable %_ptr_Uniform_int Uniform
- %main = OpFunction %void None %5
- %12 = OpLabel
- %13 = OpLoad %int %a
- %14 = OpSGreaterThan %bool %13 %int_0
- OpSelectionMerge %15 None
- OpBranchConditional %14 %16 %15
- %16 = OpLabel
- %17 = OpLoad %int %a
- %18 = OpSLessThan %bool %17 %int_100
- OpBranchConditional %18 %19 %15
- %19 = OpLabel
- OpStore %a %int_1
- OpBranch %15
- %15 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(test, test, true, true);
- }
- TEST_F(AggressiveDCETest, CountingLoopNotEliminated) {
- // #version 310 es
- //
- // precision highp float;
- // precision highp int;
- //
- // layout(location = 0) out vec4 _GLF_color;
- //
- // void main()
- // {
- // float data[1];
- // for (int c = 0; c < 1; c++) {
- // if (true) {
- // do {
- // for (int i = 0; i < 1; i++) {
- // data[i] = 1.0;
- // }
- // } while (false);
- // }
- // }
- // _GLF_color = vec4(data[0], 0.0, 0.0, 1.0);
- // }
- const std::string test =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %_GLF_color
- OpExecutionMode %main OriginUpperLeft
- OpSource ESSL 310
- OpName %main "main"
- OpName %c "c"
- OpName %i "i"
- OpName %data "data"
- OpName %_GLF_color "_GLF_color"
- OpDecorate %_GLF_color Location 0
- %void = OpTypeVoid
- %8 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %int_0 = OpConstant %int 0
- %int_1 = OpConstant %int 1
- %bool = OpTypeBool
- %float = OpTypeFloat 32
- %uint = OpTypeInt 32 0
- %uint_1 = OpConstant %uint 1
- %_arr_float_uint_1 = OpTypeArray %float %uint_1
- %_ptr_Function__arr_float_uint_1 = OpTypePointer Function %_arr_float_uint_1
- %float_1 = OpConstant %float 1
- %_ptr_Function_float = OpTypePointer Function %float
- %false = OpConstantFalse %bool
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %_GLF_color = OpVariable %_ptr_Output_v4float Output
- %float_0 = OpConstant %float 0
- %main = OpFunction %void None %8
- %26 = OpLabel
- %c = OpVariable %_ptr_Function_int Function
- %i = OpVariable %_ptr_Function_int Function
- %data = OpVariable %_ptr_Function__arr_float_uint_1 Function
- OpStore %c %int_0
- OpBranch %27
- %27 = OpLabel
- OpLoopMerge %28 %29 None
- OpBranch %30
- %30 = OpLabel
- %31 = OpLoad %int %c
- %32 = OpSLessThan %bool %31 %int_1
- OpBranchConditional %32 %33 %28
- %33 = OpLabel
- OpBranch %34
- %34 = OpLabel
- OpBranch %35
- %35 = OpLabel
- OpLoopMerge %36 %37 None
- OpBranch %38
- %38 = OpLabel
- OpStore %i %int_0
- OpBranch %39
- %39 = OpLabel
- OpLoopMerge %40 %41 None
- OpBranch %42
- %42 = OpLabel
- %43 = OpLoad %int %i
- %44 = OpSLessThan %bool %43 %int_1
- OpBranchConditional %44 %46 %40
- %46 = OpLabel
- %47 = OpLoad %int %i
- %48 = OpAccessChain %_ptr_Function_float %data %47
- OpStore %48 %float_1
- OpBranch %41
- %41 = OpLabel
- %49 = OpLoad %int %i
- %50 = OpIAdd %int %49 %int_1
- OpStore %i %50
- OpBranch %39
- %40 = OpLabel
- OpBranch %37
- %37 = OpLabel
- OpBranchConditional %false %35 %36
- %36 = OpLabel
- OpBranch %45
- %45 = OpLabel
- OpBranch %29
- %29 = OpLabel
- %51 = OpLoad %int %c
- %52 = OpIAdd %int %51 %int_1
- OpStore %c %52
- OpBranch %27
- %28 = OpLabel
- %53 = OpAccessChain %_ptr_Function_float %data %int_0
- %54 = OpLoad %float %53
- %55 = OpCompositeConstruct %v4float %54 %float_0 %float_0 %float_1
- OpStore %_GLF_color %55
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(test, test, true, true);
- }
- TEST_F(AggressiveDCETest, EliminateLoopWithUnreachable) {
- // #version 430
- //
- // layout(std430) buffer U_t
- // {
- // float g_F[10];
- // float g_S;
- // };
- //
- // layout(location = 0)out float o;
- //
- // void main(void)
- // {
- // // Useless loop
- // for (int i = 0; i<10; i++) {
- // if (g_F[i] == 0.0)
- // break;
- // else
- // break;
- // // Unreachable merge block created here.
- // // Need to edit SPIR-V to change to OpUnreachable
- // }
- // o = g_S;
- // }
- const std::string before =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %i "i"
- OpName %U_t "U_t"
- OpMemberName %U_t 0 "g_F"
- OpMemberName %U_t 1 "g_S"
- OpName %_ ""
- OpName %o "o"
- OpDecorate %_arr_float_uint_10 ArrayStride 4
- OpMemberDecorate %U_t 0 Offset 0
- OpMemberDecorate %U_t 1 Offset 40
- OpDecorate %U_t BufferBlock
- OpDecorate %_ DescriptorSet 0
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %int_0 = OpConstant %int 0
- %int_10 = OpConstant %int 10
- %bool = OpTypeBool
- %float = OpTypeFloat 32
- %uint = OpTypeInt 32 0
- %uint_10 = OpConstant %uint 10
- %_arr_float_uint_10 = OpTypeArray %float %uint_10
- %U_t = OpTypeStruct %_arr_float_uint_10 %float
- %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
- %_ = OpVariable %_ptr_Uniform_U_t Uniform
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %float_0 = OpConstant %float 0
- %int_1 = OpConstant %int 1
- %_ptr_Output_float = OpTypePointer Output %float
- %o = OpVariable %_ptr_Output_float Output
- %main = OpFunction %void None %9
- %23 = OpLabel
- %i = OpVariable %_ptr_Function_int Function
- OpStore %i %int_0
- OpBranch %24
- %24 = OpLabel
- OpLoopMerge %25 %26 None
- OpBranch %27
- %27 = OpLabel
- %28 = OpLoad %int %i
- %29 = OpSLessThan %bool %28 %int_10
- OpBranchConditional %29 %30 %25
- %30 = OpLabel
- %31 = OpLoad %int %i
- %32 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %31
- %33 = OpLoad %float %32
- %34 = OpFOrdEqual %bool %33 %float_0
- OpSelectionMerge %35 None
- OpBranchConditional %34 %36 %37
- %36 = OpLabel
- OpBranch %25
- %37 = OpLabel
- OpBranch %25
- %35 = OpLabel
- OpUnreachable
- %26 = OpLabel
- %38 = OpLoad %int %i
- %39 = OpIAdd %int %38 %int_1
- OpStore %i %39
- OpBranch %24
- %25 = OpLabel
- %40 = OpAccessChain %_ptr_Uniform_float %_ %int_1
- %41 = OpLoad %float %40
- OpStore %o %41
- OpReturn
- OpFunctionEnd
- )";
- const std::string after =
- R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %o
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %U_t "U_t"
- OpMemberName %U_t 0 "g_F"
- OpMemberName %U_t 1 "g_S"
- OpName %_ ""
- OpName %o "o"
- OpDecorate %_arr_float_uint_10 ArrayStride 4
- OpMemberDecorate %U_t 0 Offset 0
- OpMemberDecorate %U_t 1 Offset 40
- OpDecorate %U_t BufferBlock
- OpDecorate %_ DescriptorSet 0
- OpDecorate %o Location 0
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %float = OpTypeFloat 32
- %uint = OpTypeInt 32 0
- %uint_10 = OpConstant %uint 10
- %_arr_float_uint_10 = OpTypeArray %float %uint_10
- %U_t = OpTypeStruct %_arr_float_uint_10 %float
- %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
- %_ = OpVariable %_ptr_Uniform_U_t Uniform
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %int_1 = OpConstant %int 1
- %_ptr_Output_float = OpTypePointer Output %float
- %o = OpVariable %_ptr_Output_float Output
- %main = OpFunction %void None %9
- %23 = OpLabel
- OpBranch %24
- %24 = OpLabel
- OpBranch %25
- %25 = OpLabel
- %40 = OpAccessChain %_ptr_Uniform_float %_ %int_1
- %41 = OpLoad %float %40
- OpStore %o %41
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(before, after, true, true);
- }
- TEST_F(AggressiveDCETest, DeadHlslCounterBufferGOOGLE) {
- // We are able to remove "local2" because it is not loaded, but have to keep
- // the stores to "local1".
- const std::string test =
- R"(
- ; CHECK-NOT: OpDecorateId
- ; CHECK: [[var:%\w+]] = OpVariable
- ; CHECK-NOT: OpVariable
- ; CHECK: [[ac:%\w+]] = OpAccessChain {{%\w+}} [[var]]
- ; CHECK: OpStore [[ac]]
- OpCapability Shader
- OpExtension "SPV_GOOGLE_hlsl_functionality1"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %1 "main"
- OpExecutionMode %1 LocalSize 32 1 1
- OpSource HLSL 600
- OpDecorate %_runtimearr_v2float ArrayStride 8
- OpMemberDecorate %_struct_3 0 Offset 0
- OpDecorate %_struct_3 BufferBlock
- OpMemberDecorate %_struct_4 0 Offset 0
- OpDecorate %_struct_4 BufferBlock
- OpDecorateId %5 HlslCounterBufferGOOGLE %6
- OpDecorate %5 DescriptorSet 0
- OpDecorate %5 Binding 0
- OpDecorate %6 DescriptorSet 0
- OpDecorate %6 Binding 1
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %_runtimearr_v2float = OpTypeRuntimeArray %v2float
- %_struct_3 = OpTypeStruct %_runtimearr_v2float
- %_ptr_Uniform__struct_3 = OpTypePointer Uniform %_struct_3
- %int = OpTypeInt 32 1
- %_struct_4 = OpTypeStruct %int
- %_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4
- %void = OpTypeVoid
- %13 = OpTypeFunction %void
- %19 = OpConstantNull %v2float
- %int_0 = OpConstant %int 0
- %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
- %5 = OpVariable %_ptr_Uniform__struct_3 Uniform
- %6 = OpVariable %_ptr_Uniform__struct_4 Uniform
- %1 = OpFunction %void None %13
- %22 = OpLabel
- %23 = OpAccessChain %_ptr_Uniform_v2float %5 %int_0 %int_0
- OpStore %23 %19
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(test, true);
- }
- TEST_F(AggressiveDCETest, Dead) {
- // We are able to remove "local2" because it is not loaded, but have to keep
- // the stores to "local1".
- const std::string test =
- R"(
- ; CHECK: OpCapability
- ; CHECK-NOT: OpMemberDecorateStringGOOGLE
- ; CHECK: OpFunctionEnd
- OpCapability Shader
- OpExtension "SPV_GOOGLE_hlsl_functionality1"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %VSMain "VSMain"
- OpSource HLSL 500
- OpName %VSMain "VSMain"
- OpName %PSInput "PSInput"
- OpMemberName %PSInput 0 "Pos"
- OpMemberName %PSInput 1 "uv"
- OpMemberDecorateStringGOOGLE %PSInput 0 HlslSemanticGOOGLE "SV_POSITION"
- OpMemberDecorateStringGOOGLE %PSInput 1 HlslSemanticGOOGLE "TEX_COORD"
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v4float = OpTypeVector %float 4
- %PSInput = OpTypeStruct %v4float %v2float
- %VSMain = OpFunction %void None %5
- %9 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(test, true);
- }
- TEST_F(AggressiveDCETest, DeadInfiniteLoop) {
- const std::string test = R"(
- ; CHECK: OpSwitch {{%\w+}} {{%\w+}} {{\w+}} {{%\w+}} {{\w+}} [[block:%\w+]]
- ; CHECK: [[block]] = OpLabel
- ; CHECK-NEXT: OpBranch [[block:%\w+]]
- ; CHECK: [[block]] = OpLabel
- ; CHECK-NEXT: OpBranch [[block:%\w+]]
- ; CHECK: [[block]] = OpLabel
- ; CHECK-NEXT: OpReturn
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %2 "main"
- OpExecutionMode %2 OriginUpperLeft
- %6 = OpTypeVoid
- %7 = OpTypeFunction %6
- %8 = OpTypeFloat 32
- %9 = OpTypeVector %8 3
- %10 = OpTypeFunction %9
- %11 = OpConstant %8 1
- %12 = OpConstantComposite %9 %11 %11 %11
- %13 = OpTypeInt 32 1
- %32 = OpUndef %13
- %2 = OpFunction %6 None %7
- %33 = OpLabel
- OpBranch %34
- %34 = OpLabel
- OpLoopMerge %35 %36 None
- OpBranch %37
- %37 = OpLabel
- %38 = OpFunctionCall %9 %39
- OpSelectionMerge %40 None
- OpSwitch %32 %40 14 %41 58 %42
- %42 = OpLabel
- OpBranch %43
- %43 = OpLabel
- OpLoopMerge %44 %45 None
- OpBranch %45
- %45 = OpLabel
- OpBranch %43
- %44 = OpLabel
- OpUnreachable
- %41 = OpLabel
- OpBranch %36
- %40 = OpLabel
- OpBranch %36
- %36 = OpLabel
- OpBranch %34
- %35 = OpLabel
- OpReturn
- OpFunctionEnd
- %39 = OpFunction %9 None %10
- %46 = OpLabel
- OpReturnValue %12
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(test, true);
- }
- TEST_F(AggressiveDCETest, DeadInfiniteLoopReturnValue) {
- const std::string test = R"(
- ; CHECK: [[vec3:%\w+]] = OpTypeVector
- ; CHECK: [[undef:%\w+]] = OpUndef [[vec3]]
- ; CHECK: OpSwitch {{%\w+}} {{%\w+}} {{\w+}} {{%\w+}} {{\w+}} [[block:%\w+]]
- ; CHECK: [[block]] = OpLabel
- ; CHECK-NEXT: OpBranch [[block:%\w+]]
- ; CHECK: [[block]] = OpLabel
- ; CHECK-NEXT: OpBranch [[block:%\w+]]
- ; CHECK: [[block]] = OpLabel
- ; CHECK-NEXT: OpReturnValue [[undef]]
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %2 "main"
- OpExecutionMode %2 OriginUpperLeft
- %6 = OpTypeVoid
- %7 = OpTypeFunction %6
- %8 = OpTypeFloat 32
- %9 = OpTypeVector %8 3
- %10 = OpTypeFunction %9
- %11 = OpConstant %8 1
- %12 = OpConstantComposite %9 %11 %11 %11
- %13 = OpTypeInt 32 1
- %32 = OpUndef %13
- %2 = OpFunction %6 None %7
- %entry = OpLabel
- %call = OpFunctionCall %9 %func
- OpReturn
- OpFunctionEnd
- %func = OpFunction %9 None %10
- %33 = OpLabel
- OpBranch %34
- %34 = OpLabel
- OpLoopMerge %35 %36 None
- OpBranch %37
- %37 = OpLabel
- %38 = OpFunctionCall %9 %39
- OpSelectionMerge %40 None
- OpSwitch %32 %40 14 %41 58 %42
- %42 = OpLabel
- OpBranch %43
- %43 = OpLabel
- OpLoopMerge %44 %45 None
- OpBranch %45
- %45 = OpLabel
- OpBranch %43
- %44 = OpLabel
- OpUnreachable
- %41 = OpLabel
- OpBranch %36
- %40 = OpLabel
- OpBranch %36
- %36 = OpLabel
- OpBranch %34
- %35 = OpLabel
- OpReturnValue %12
- OpFunctionEnd
- %39 = OpFunction %9 None %10
- %46 = OpLabel
- OpReturnValue %12
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(test, true);
- }
- TEST_F(AggressiveDCETest, TestVariablePointer) {
- const std::string before =
- R"(OpCapability Shader
- OpCapability VariablePointers
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %2 "main"
- OpExecutionMode %2 LocalSize 1 1 1
- OpSource GLSL 450
- OpMemberDecorate %_struct_3 0 Offset 0
- OpDecorate %_struct_3 Block
- OpDecorate %4 DescriptorSet 0
- OpDecorate %4 Binding 0
- OpDecorate %_ptr_StorageBuffer_int ArrayStride 4
- OpDecorate %_arr_int_int_128 ArrayStride 4
- %void = OpTypeVoid
- %8 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %int_128 = OpConstant %int 128
- %_arr_int_int_128 = OpTypeArray %int %int_128
- %_struct_3 = OpTypeStruct %_arr_int_int_128
- %_ptr_StorageBuffer__struct_3 = OpTypePointer StorageBuffer %_struct_3
- %4 = OpVariable %_ptr_StorageBuffer__struct_3 StorageBuffer
- %bool = OpTypeBool
- %true = OpConstantTrue %bool
- %int_0 = OpConstant %int 0
- %int_1 = OpConstant %int 1
- %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
- %2 = OpFunction %void None %8
- %16 = OpLabel
- %17 = OpAccessChain %_ptr_StorageBuffer_int %4 %int_0 %int_0
- OpBranch %18
- %18 = OpLabel
- %19 = OpPhi %_ptr_StorageBuffer_int %17 %16 %20 %21
- OpLoopMerge %22 %21 None
- OpBranchConditional %true %23 %22
- %23 = OpLabel
- OpStore %19 %int_0
- OpBranch %21
- %21 = OpLabel
- %20 = OpPtrAccessChain %_ptr_StorageBuffer_int %19 %int_1
- OpBranch %18
- %22 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(before, before, true, true);
- }
- TEST_F(AggressiveDCETest, DeadInputInterfaceV13) {
- const std::string spirv = R"(
- ; CHECK: OpEntryPoint GLCompute %main "main"
- ; CHECK-NOT: OpVariable
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %dead
- OpExecutionMode %main LocalSize 1 1 1
- OpName %main "main"
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %ptr_input_int = OpTypePointer Input %int
- %dead = OpVariable %ptr_input_int Input
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_UNIVERSAL_1_3);
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, DeadInputInterfaceV14) {
- const std::string spirv = R"(
- ; CHECK: OpEntryPoint GLCompute %main "main"
- ; CHECK-NOT: OpVariable
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %dead
- OpExecutionMode %main LocalSize 1 1 1
- OpName %main "main"
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %ptr_input_int = OpTypePointer Input %int
- %dead = OpVariable %ptr_input_int Input
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, DeadInterfaceV14) {
- const std::string spirv = R"(
- ; CHECK-NOT: OpEntryPoint GLCompute %main "main" %
- ; CHECK: OpEntryPoint GLCompute %main "main"
- ; CHECK-NOT: OpVariable
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %dead
- OpExecutionMode %main LocalSize 1 1 1
- OpName %main "main"
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %ptr_private_int = OpTypePointer Private %int
- %dead = OpVariable %ptr_private_int Private
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, DeadInterfacesV14) {
- const std::string spirv = R"(
- ; CHECK: OpEntryPoint GLCompute %main "main" %live1 %live2
- ; CHECK-NOT: %dead
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main" %live1 %dead1 %dead2 %live2
- OpExecutionMode %main LocalSize 1 1 1
- OpName %main "main"
- OpName %live1 "live1"
- OpName %live2 "live2"
- OpName %dead1 "dead1"
- OpName %dead2 "dead2"
- %void = OpTypeVoid
- %int = OpTypeInt 32 0
- %int0 = OpConstant %int 0
- %ptr_ssbo_int = OpTypePointer StorageBuffer %int
- %live1 = OpVariable %ptr_ssbo_int StorageBuffer
- %live2 = OpVariable %ptr_ssbo_int StorageBuffer
- %dead1 = OpVariable %ptr_ssbo_int StorageBuffer
- %dead2 = OpVariable %ptr_ssbo_int StorageBuffer
- %void_fn = OpTypeFunction %void
- %main = OpFunction %void None %void_fn
- %entry = OpLabel
- OpStore %live1 %int0
- OpStore %live2 %int0
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, PreserveBindings) {
- const std::string spirv = R"(
- ; CHECK: OpDecorate %unusedSampler DescriptorSet 0
- ; CHECK: OpDecorate %unusedSampler Binding 0
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %unusedSampler "unusedSampler"
- OpDecorate %unusedSampler DescriptorSet 0
- OpDecorate %unusedSampler Binding 0
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
- %8 = OpTypeSampledImage %7
- %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
- %unusedSampler = OpVariable %_ptr_UniformConstant_8 UniformConstant
- %main = OpFunction %void None %5
- %10 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
- OptimizerOptions()->preserve_bindings_ = true;
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, PreserveSpecConstants) {
- const std::string spirv = R"(
- ; CHECK: OpName %specConstant "specConstant"
- ; CHECK: %specConstant = OpSpecConstant %int 0
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 430
- OpName %main "main"
- OpName %specConstant "specConstant"
- OpDecorate %specConstant SpecId 0
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %specConstant = OpSpecConstant %int 0
- %main = OpFunction %void None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
- OptimizerOptions()->preserve_spec_constants_ = true;
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, LiveDecorateId) {
- const std::string spirv = R"(OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %1 "main" %2
- OpExecutionMode %1 LocalSize 8 1 1
- OpDecorate %2 DescriptorSet 0
- OpDecorate %2 Binding 0
- OpDecorateId %3 UniformId %uint_2
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %uint_2 = OpConstant %uint 2
- %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
- %2 = OpVariable %_ptr_StorageBuffer_uint StorageBuffer
- %8 = OpTypeFunction %void
- %1 = OpFunction %void None %8
- %9 = OpLabel
- %3 = OpLoad %uint %2
- OpStore %2 %3
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
- OptimizerOptions()->preserve_spec_constants_ = true;
- SinglePassRunAndCheck<AggressiveDCEPass>(spirv, spirv, true);
- }
- TEST_F(AggressiveDCETest, LiveDecorateIdOnGroup) {
- const std::string spirv = R"(OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %1 "main" %2
- OpExecutionMode %1 LocalSize 8 1 1
- OpDecorate %2 DescriptorSet 0
- OpDecorate %2 Binding 0
- OpDecorateId %3 UniformId %uint_2
- %3 = OpDecorationGroup
- OpGroupDecorate %3 %5
- %void = OpTypeVoid
- %uint = OpTypeInt 32 0
- %uint_2 = OpConstant %uint 2
- %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
- %2 = OpVariable %_ptr_StorageBuffer_uint StorageBuffer
- %9 = OpTypeFunction %void
- %1 = OpFunction %void None %9
- %10 = OpLabel
- %5 = OpLoad %uint %2
- OpStore %2 %5
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
- OptimizerOptions()->preserve_spec_constants_ = true;
- SinglePassRunAndCheck<AggressiveDCEPass>(spirv, spirv, true);
- }
- TEST_F(AggressiveDCETest, NoEliminateForwardPointer) {
- // clang-format off
- //
- // #version 450
- // #extension GL_EXT_buffer_reference : enable
- //
- // // forward reference
- // layout(buffer_reference) buffer blockType;
- //
- // layout(buffer_reference, std430, buffer_reference_align = 16) buffer blockType {
- // int x;
- // blockType next;
- // };
- //
- // layout(std430) buffer rootBlock {
- // blockType root;
- // } r;
- //
- // void main()
- // {
- // blockType b = r.root;
- // b = b.next;
- // b.x = 531;
- // }
- //
- // clang-format on
- const std::string predefs1 =
- R"(OpCapability Shader
- OpCapability PhysicalStorageBufferAddresses
- OpExtension "SPV_EXT_physical_storage_buffer"
- OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel PhysicalStorageBuffer64 GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 1 1 1
- OpSource GLSL 450
- OpSourceExtension "GL_EXT_buffer_reference"
- )";
- const std::string names_before =
- R"(OpName %main "main"
- OpName %blockType "blockType"
- OpMemberName %blockType 0 "x"
- OpMemberName %blockType 1 "next"
- OpName %b "b"
- OpName %rootBlock "rootBlock"
- OpMemberName %rootBlock 0 "root"
- OpName %r "r"
- OpMemberDecorate %blockType 0 Offset 0
- OpMemberDecorate %blockType 1 Offset 8
- OpDecorate %blockType Block
- OpDecorate %b AliasedPointer
- OpMemberDecorate %rootBlock 0 Offset 0
- OpDecorate %rootBlock Block
- OpDecorate %r DescriptorSet 0
- OpDecorate %r Binding 0
- )";
- const std::string names_after =
- R"(OpName %main "main"
- OpName %blockType "blockType"
- OpMemberName %blockType 0 "x"
- OpMemberName %blockType 1 "next"
- OpName %rootBlock "rootBlock"
- OpMemberName %rootBlock 0 "root"
- OpName %r "r"
- OpMemberDecorate %blockType 0 Offset 0
- OpMemberDecorate %blockType 1 Offset 8
- OpDecorate %blockType Block
- OpMemberDecorate %rootBlock 0 Offset 0
- OpDecorate %rootBlock Block
- OpDecorate %r DescriptorSet 0
- OpDecorate %r Binding 0
- )";
- const std::string predefs2_before =
- R"(%void = OpTypeVoid
- %3 = OpTypeFunction %void
- OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer
- %int = OpTypeInt 32 1
- %blockType = OpTypeStruct %int %_ptr_PhysicalStorageBuffer_blockType
- %_ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %blockType
- %_ptr_Function__ptr_PhysicalStorageBuffer_blockType = OpTypePointer Function %_ptr_PhysicalStorageBuffer_blockType
- %rootBlock = OpTypeStruct %_ptr_PhysicalStorageBuffer_blockType
- %_ptr_StorageBuffer_rootBlock = OpTypePointer StorageBuffer %rootBlock
- %r = OpVariable %_ptr_StorageBuffer_rootBlock StorageBuffer
- %int_0 = OpConstant %int 0
- %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBuffer_blockType
- %int_1 = OpConstant %int 1
- %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_blockType
- %int_531 = OpConstant %int 531
- %_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
- )";
- const std::string predefs2_after =
- R"(%void = OpTypeVoid
- %8 = OpTypeFunction %void
- OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer
- %int = OpTypeInt 32 1
- %blockType = OpTypeStruct %int %_ptr_PhysicalStorageBuffer_blockType
- %_ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %blockType
- %rootBlock = OpTypeStruct %_ptr_PhysicalStorageBuffer_blockType
- %_ptr_StorageBuffer_rootBlock = OpTypePointer StorageBuffer %rootBlock
- %r = OpVariable %_ptr_StorageBuffer_rootBlock StorageBuffer
- %int_0 = OpConstant %int 0
- %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBuffer_blockType
- %int_1 = OpConstant %int 1
- %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_blockType
- %int_531 = OpConstant %int 531
- %_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
- )";
- const std::string func_before =
- R"(%main = OpFunction %void None %3
- %5 = OpLabel
- %b = OpVariable %_ptr_Function__ptr_PhysicalStorageBuffer_blockType Function
- %16 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType %r %int_0
- %17 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %16
- %21 = OpAccessChain %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType %17 %int_1
- %22 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8
- OpStore %b %22
- %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %22 %int_0
- OpStore %26 %int_531 Aligned 16
- OpReturn
- OpFunctionEnd
- )";
- const std::string func_after =
- R"(%main = OpFunction %void None %8
- %19 = OpLabel
- %20 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType %r %int_0
- %21 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %20
- %22 = OpAccessChain %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType %21 %int_1
- %23 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %22 Aligned 8
- %24 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %23 %int_0
- OpStore %24 %int_531 Aligned 16
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(
- predefs1 + names_before + predefs2_before + func_before,
- predefs1 + names_after + predefs2_after + func_after, true, true);
- }
- TEST_F(AggressiveDCETest, MultipleFunctionProcessIndependently) {
- const std::string spirv = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %entryHistogram "entryHistogram" %gl_GlobalInvocationID %gl_LocalInvocationIndex
- OpEntryPoint GLCompute %entryAverage "entryAverage" %gl_GlobalInvocationID %gl_LocalInvocationIndex
- OpExecutionMode %entryHistogram LocalSize 16 16 1
- OpExecutionMode %entryAverage LocalSize 256 1 1
- OpSource HLSL 640
- OpName %type_RWStructuredBuffer_uint "type.RWStructuredBuffer.uint"
- OpName %uHistogram "uHistogram"
- OpName %type_ACSBuffer_counter "type.ACSBuffer.counter"
- OpMemberName %type_ACSBuffer_counter 0 "counter"
- OpName %counter_var_uHistogram "counter.var.uHistogram"
- OpName %sharedHistogram "sharedHistogram"
- OpName %entryHistogram "entryHistogram"
- OpName %param_var_id "param.var.id"
- OpName %param_var_idx "param.var.idx"
- OpName %entryAverage "entryAverage"
- OpName %param_var_id_0 "param.var.id"
- OpName %param_var_idx_0 "param.var.idx"
- OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
- OpDecorate %gl_LocalInvocationIndex BuiltIn LocalInvocationIndex
- OpDecorate %uHistogram DescriptorSet 0
- OpDecorate %uHistogram Binding 0
- OpDecorate %counter_var_uHistogram DescriptorSet 0
- OpDecorate %counter_var_uHistogram Binding 1
- OpDecorate %_runtimearr_uint ArrayStride 4
- OpMemberDecorate %type_RWStructuredBuffer_uint 0 Offset 0
- OpDecorate %type_RWStructuredBuffer_uint BufferBlock
- OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0
- OpDecorate %type_ACSBuffer_counter BufferBlock
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %uint_4 = OpConstant %uint 4
- %uint_8 = OpConstant %uint 8
- %uint_16 = OpConstant %uint 16
- %uint_32 = OpConstant %uint 32
- %uint_64 = OpConstant %uint 64
- %uint_128 = OpConstant %uint 128
- %uint_256 = OpConstant %uint 256
- %uint_512 = OpConstant %uint 512
- %uint_254 = OpConstant %uint 254
- %uint_255 = OpConstant %uint 255
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %_runtimearr_uint = OpTypeRuntimeArray %uint
- %type_RWStructuredBuffer_uint = OpTypeStruct %_runtimearr_uint
- %_ptr_Uniform_type_RWStructuredBuffer_uint = OpTypePointer Uniform %type_RWStructuredBuffer_uint
- %type_ACSBuffer_counter = OpTypeStruct %int
- %_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter
- %_arr_uint_uint_256 = OpTypeArray %uint %uint_256
- %_ptr_Workgroup__arr_uint_uint_256 = OpTypePointer Workgroup %_arr_uint_uint_256
- %v3uint = OpTypeVector %uint 3
- %_ptr_Input_v3uint = OpTypePointer Input %v3uint
- %_ptr_Input_uint = OpTypePointer Input %uint
- %void = OpTypeVoid
- %49 = OpTypeFunction %void
- %_ptr_Function_v3uint = OpTypePointer Function %v3uint
- %_ptr_Function_uint = OpTypePointer Function %uint
- %52 = OpTypeFunction %void %_ptr_Function_v3uint %_ptr_Function_uint
- %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
- %uint_264 = OpConstant %uint 264
- %bool = OpTypeBool
- %_ptr_Uniform_uint = OpTypePointer Uniform %uint
- %uHistogram = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_uint Uniform
- %counter_var_uHistogram = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
- %sharedHistogram = OpVariable %_ptr_Workgroup__arr_uint_uint_256 Workgroup
- %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
- %gl_LocalInvocationIndex = OpVariable %_ptr_Input_uint Input
- %entryHistogram = OpFunction %void None %49
- %57 = OpLabel
- %param_var_id = OpVariable %_ptr_Function_v3uint Function
- %param_var_idx = OpVariable %_ptr_Function_uint Function
- %58 = OpLoad %v3uint %gl_GlobalInvocationID
- %59 = OpLoad %uint %gl_LocalInvocationIndex
- %79 = OpAccessChain %_ptr_Workgroup_uint %sharedHistogram %int_0
- %80 = OpAtomicIAdd %uint %79 %uint_1 %uint_0 %uint_1
- OpReturn
- OpFunctionEnd
- %entryAverage = OpFunction %void None %49
- %63 = OpLabel
- %param_var_id_0 = OpVariable %_ptr_Function_v3uint Function
- %param_var_idx_0 = OpVariable %_ptr_Function_uint Function
- %64 = OpLoad %v3uint %gl_GlobalInvocationID
- %65 = OpLoad %uint %gl_LocalInvocationIndex
- OpStore %param_var_idx_0 %65
- %83 = OpAccessChain %_ptr_Workgroup_uint %sharedHistogram %65
- OpStore %83 %uint_0
- ; CHECK: [[ieq:%\w+]] = OpIEqual
- ; CHECK-NEXT: OpSelectionMerge [[merge:%\w+]]
- ; CHECK-NEXT: OpBranchConditional [[ieq]] [[not_elim:%\w+]] [[merge]]
- ; CHECK-NEXT: [[not_elim]] = OpLabel
- ; CHECK: [[merge]] = OpLabel
- OpControlBarrier %uint_2 %uint_2 %uint_264
- %85 = OpIEqual %bool %65 %uint_0
- OpSelectionMerge %89 None
- OpBranchConditional %85 %86 %89
- %86 = OpLabel
- %88 = OpAccessChain %_ptr_Workgroup_uint %sharedHistogram %65
- OpStore %88 %uint_1
- OpBranch %89
- %89 = OpLabel
- OpControlBarrier %uint_2 %uint_2 %uint_264
- %91 = OpAccessChain %_ptr_Workgroup_uint %sharedHistogram %65
- %92 = OpLoad %uint %91
- %94 = OpAccessChain %_ptr_Uniform_uint %uHistogram %int_0 %65
- OpStore %94 %92
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_UNIVERSAL_1_3);
- SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
- }
- TEST_F(AggressiveDCETest, DebugInfoKeepInFunctionElimStoreVar) {
- // Verify that dead local variable tc and store eliminated but all
- // in-function debuginfo kept.
- //
- // The SPIR-V has been inlined and local single store eliminated
- //
- // Texture2D g_tColor;
- // SamplerState g_sAniso;
- //
- // struct PS_INPUT {
- // float2 vTextureCoords : TEXCOORD2;
- // };
- //
- // struct PS_OUTPUT {
- // float4 vColor : SV_Target0;
- // };
- //
- // PS_OUTPUT MainPs(PS_INPUT i) {
- // PS_OUTPUT ps_output;
- // float2 tc = i.vTextureCoords.xy;
- // ps_output.vColor = g_tColor.Sample(g_sAniso, tc);
- // return ps_output;
- // }
- const std::string text = R"(
- OpCapability Shader
- %1 = OpExtInstImport "OpenCL.DebugInfo.100"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_sAniso %in_var_TEXCOORD2 %out_var_SV_Target0
- OpExecutionMode %MainPs OriginUpperLeft
- %7 = OpString "foo.frag"
- %8 = OpString "PS_OUTPUT"
- %9 = OpString "float"
- %10 = OpString "vColor"
- %11 = OpString "PS_INPUT"
- %12 = OpString "vTextureCoords"
- %13 = OpString "@type.2d.image"
- %14 = OpString "type.2d.image"
- %15 = OpString "Texture2D.TemplateParam"
- %16 = OpString "src.MainPs"
- %17 = OpString "tc"
- %18 = OpString "ps_output"
- %19 = OpString "i"
- %20 = OpString "@type.sampler"
- %21 = OpString "type.sampler"
- %22 = OpString "g_sAniso"
- %23 = OpString "g_tColor"
- OpName %type_2d_image "type.2d.image"
- OpName %g_tColor "g_tColor"
- OpName %type_sampler "type.sampler"
- OpName %g_sAniso "g_sAniso"
- OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
- OpName %out_var_SV_Target0 "out.var.SV_Target0"
- OpName %MainPs "MainPs"
- OpName %PS_INPUT "PS_INPUT"
- OpMemberName %PS_INPUT 0 "vTextureCoords"
- OpName %param_var_i "param.var.i"
- OpName %PS_OUTPUT "PS_OUTPUT"
- OpMemberName %PS_OUTPUT 0 "vColor"
- OpName %type_sampled_image "type.sampled.image"
- OpDecorate %in_var_TEXCOORD2 Location 0
- OpDecorate %out_var_SV_Target0 Location 0
- OpDecorate %g_tColor DescriptorSet 0
- OpDecorate %g_tColor Binding 0
- OpDecorate %g_sAniso DescriptorSet 0
- OpDecorate %g_sAniso Binding 1
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %uint = OpTypeInt 32 0
- %uint_32 = OpConstant %uint 32
- %float = OpTypeFloat 32
- %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
- %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
- %type_sampler = OpTypeSampler
- %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
- %v2float = OpTypeVector %float 2
- %_ptr_Input_v2float = OpTypePointer Input %v2float
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %uint_128 = OpConstant %uint 128
- %uint_0 = OpConstant %uint 0
- %uint_64 = OpConstant %uint 64
- %45 = OpTypeFunction %void
- %PS_INPUT = OpTypeStruct %v2float
- %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
- %PS_OUTPUT = OpTypeStruct %v4float
- %47 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
- %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
- %_ptr_Function_v2float = OpTypePointer Function %v2float
- %type_sampled_image = OpTypeSampledImage %type_2d_image
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
- %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
- %in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
- %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
- %51 = OpExtInst %void %1 DebugInfoNone
- %52 = OpExtInst %void %1 DebugExpression
- %53 = OpExtInst %void %1 DebugOperation Deref
- %54 = OpExtInst %void %1 DebugExpression %53
- %55 = OpExtInst %void %1 DebugSource %7
- %56 = OpExtInst %void %1 DebugCompilationUnit 1 4 %55 HLSL
- %57 = OpExtInst %void %1 DebugTypeComposite %8 Structure %55 10 1 %56 %8 %uint_128 FlagIsProtected|FlagIsPrivate %58
- %59 = OpExtInst %void %1 DebugTypeBasic %9 %uint_32 Float
- %60 = OpExtInst %void %1 DebugTypeVector %59 4
- %58 = OpExtInst %void %1 DebugTypeMember %10 %60 %55 12 5 %57 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
- %61 = OpExtInst %void %1 DebugTypeComposite %11 Structure %55 5 1 %56 %11 %uint_64 FlagIsProtected|FlagIsPrivate %62
- %63 = OpExtInst %void %1 DebugTypeVector %59 2
- %62 = OpExtInst %void %1 DebugTypeMember %12 %63 %55 7 5 %61 %uint_0 %uint_64 FlagIsProtected|FlagIsPrivate
- %64 = OpExtInst %void %1 DebugTypeComposite %13 Class %55 0 0 %56 %14 %51 FlagIsProtected|FlagIsPrivate
- %65 = OpExtInst %void %1 DebugTypeTemplateParameter %15 %59 %51 %55 0 0
- %66 = OpExtInst %void %1 DebugTypeTemplate %64 %65
- %67 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %57 %61
- %68 = OpExtInst %void %1 DebugFunction %16 %67 %55 15 1 %56 %16 FlagIsProtected|FlagIsPrivate 16 %51
- %69 = OpExtInst %void %1 DebugLexicalBlock %55 16 1 %68
- %70 = OpExtInst %void %1 DebugLocalVariable %17 %63 %55 19 12 %69 FlagIsLocal
- %71 = OpExtInst %void %1 DebugLocalVariable %18 %57 %55 17 15 %69 FlagIsLocal
- %72 = OpExtInst %void %1 DebugLocalVariable %19 %61 %55 15 29 %68 FlagIsLocal 1
- %73 = OpExtInst %void %1 DebugTypeComposite %20 Structure %55 0 0 %56 %21 %51 FlagIsProtected|FlagIsPrivate
- %74 = OpExtInst %void %1 DebugGlobalVariable %22 %73 %55 3 14 %56 %22 %g_sAniso FlagIsDefinition
- %75 = OpExtInst %void %1 DebugGlobalVariable %23 %64 %55 1 11 %56 %23 %g_tColor FlagIsDefinition
- %MainPs = OpFunction %void None %45
- %76 = OpLabel
- %107 = OpExtInst %void %1 DebugScope %69
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugScope %69
- %78 = OpVariable %_ptr_Function_PS_OUTPUT Function
- %79 = OpVariable %_ptr_Function_v2float Function
- %108 = OpExtInst %void %1 DebugNoScope
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugNoScope
- %81 = OpVariable %_ptr_Function_PS_OUTPUT Function
- %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
- %82 = OpLoad %v2float %in_var_TEXCOORD2
- %83 = OpCompositeConstruct %PS_INPUT %82
- OpStore %param_var_i %83
- %109 = OpExtInst %void %1 DebugScope %68
- %85 = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
- %110 = OpExtInst %void %1 DebugScope %69
- %87 = OpExtInst %void %1 DebugDeclare %71 %78 %52
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugScope %68
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugScope %69
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugDeclare %71 %78 %52
- OpLine %7 19 17
- %88 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
- %89 = OpLoad %v2float %88
- OpLine %7 19 12
- OpStore %79 %89
- ;CHECK-NOT: OpStore %79 %89
- OpLine %7 19 12
- %106 = OpExtInst %void %1 DebugValue %70 %89 %52
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugValue %70 %89 %52
- OpLine %7 20 26
- %91 = OpLoad %type_2d_image %g_tColor
- OpLine %7 20 46
- %92 = OpLoad %type_sampler %g_sAniso
- OpLine %7 20 26
- %94 = OpSampledImage %type_sampled_image %91 %92
- %95 = OpImageSampleImplicitLod %v4float %94 %89 None
- OpLine %7 20 5
- %96 = OpAccessChain %_ptr_Function_v4float %78 %int_0
- OpStore %96 %95
- OpLine %7 21 12
- %97 = OpLoad %PS_OUTPUT %78
- OpLine %7 21 5
- OpStore %81 %97
- %111 = OpExtInst %void %1 DebugNoScope
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugNoScope
- %100 = OpCompositeExtract %v4float %97 0
- OpStore %out_var_SV_Target0 %100
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, ShaderDebugInfoKeepInFunctionElimStoreVar) {
- // Verify that dead local variable tc and store eliminated but all
- // in-function NonSemantic Shader debuginfo kept.
- const std::string text = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_non_semantic_info"
- %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_sAniso %in_var_TEXCOORD2 %out_var_SV_Target0
- OpExecutionMode %MainPs OriginUpperLeft
- %7 = OpString "foo.frag"
- %8 = OpString "PS_OUTPUT"
- %9 = OpString "float"
- %10 = OpString "vColor"
- %11 = OpString "PS_INPUT"
- %12 = OpString "vTextureCoords"
- %13 = OpString "@type.2d.image"
- %14 = OpString "type.2d.image"
- %15 = OpString "Texture2D.TemplateParam"
- %16 = OpString "src.MainPs"
- %17 = OpString "tc"
- %18 = OpString "ps_output"
- %19 = OpString "i"
- %20 = OpString "@type.sampler"
- %21 = OpString "type.sampler"
- %22 = OpString "g_sAniso"
- %23 = OpString "g_tColor"
- OpName %type_2d_image "type.2d.image"
- OpName %g_tColor "g_tColor"
- OpName %type_sampler "type.sampler"
- OpName %g_sAniso "g_sAniso"
- OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
- OpName %out_var_SV_Target0 "out.var.SV_Target0"
- OpName %MainPs "MainPs"
- OpName %PS_INPUT "PS_INPUT"
- OpMemberName %PS_INPUT 0 "vTextureCoords"
- OpName %param_var_i "param.var.i"
- OpName %PS_OUTPUT "PS_OUTPUT"
- OpMemberName %PS_OUTPUT 0 "vColor"
- OpName %type_sampled_image "type.sampled.image"
- OpDecorate %in_var_TEXCOORD2 Location 0
- OpDecorate %out_var_SV_Target0 Location 0
- OpDecorate %g_tColor DescriptorSet 0
- OpDecorate %g_tColor Binding 0
- OpDecorate %g_sAniso DescriptorSet 0
- OpDecorate %g_sAniso Binding 1
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %uint = OpTypeInt 32 0
- %uint_32 = OpConstant %uint 32
- %float = OpTypeFloat 32
- %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
- %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
- %type_sampler = OpTypeSampler
- %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
- %v2float = OpTypeVector %float 2
- %_ptr_Input_v2float = OpTypePointer Input %v2float
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %uint_128 = OpConstant %uint 128
- %uint_0 = OpConstant %uint 0
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %uint_3 = OpConstant %uint 3
- %uint_4 = OpConstant %uint 4
- %uint_5 = OpConstant %uint 5
- %uint_7 = OpConstant %uint 7
- %uint_8 = OpConstant %uint 8
- %uint_10 = OpConstant %uint 10
- %uint_11 = OpConstant %uint 11
- %uint_12 = OpConstant %uint 12
- %uint_14 = OpConstant %uint 14
- %uint_15 = OpConstant %uint 15
- %uint_16 = OpConstant %uint 16
- %uint_17 = OpConstant %uint 17
- %uint_19 = OpConstant %uint 19
- %uint_20 = OpConstant %uint 20
- %uint_21 = OpConstant %uint 21
- %uint_25 = OpConstant %uint 25
- %uint_29 = OpConstant %uint 29
- %uint_30 = OpConstant %uint 30
- %uint_35 = OpConstant %uint 35
- %uint_41 = OpConstant %uint 41
- %uint_48 = OpConstant %uint 48
- %uint_53 = OpConstant %uint 53
- %uint_64 = OpConstant %uint 64
- %45 = OpTypeFunction %void
- %PS_INPUT = OpTypeStruct %v2float
- %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
- %PS_OUTPUT = OpTypeStruct %v4float
- %47 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
- %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
- %_ptr_Function_v2float = OpTypePointer Function %v2float
- %type_sampled_image = OpTypeSampledImage %type_2d_image
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
- %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
- %in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
- %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
- %51 = OpExtInst %void %1 DebugInfoNone
- %52 = OpExtInst %void %1 DebugExpression
- %53 = OpExtInst %void %1 DebugOperation %uint_0
- %54 = OpExtInst %void %1 DebugExpression %53
- %55 = OpExtInst %void %1 DebugSource %7
- %56 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %55 %uint_5
- %59 = OpExtInst %void %1 DebugTypeBasic %9 %uint_32 %uint_3 %uint_0
- %60 = OpExtInst %void %1 DebugTypeVector %59 %uint_4
- %58 = OpExtInst %void %1 DebugTypeMember %10 %60 %55 %uint_12 %uint_5 %uint_0 %uint_128 %uint_3
- %57 = OpExtInst %void %1 DebugTypeComposite %8 %uint_1 %55 %uint_10 %uint_1 %56 %8 %uint_128 %uint_3 %58
- %63 = OpExtInst %void %1 DebugTypeVector %59 %uint_2
- %62 = OpExtInst %void %1 DebugTypeMember %12 %63 %55 %uint_7 %uint_5 %uint_0 %uint_64 %uint_3
- %61 = OpExtInst %void %1 DebugTypeComposite %11 %uint_1 %55 %uint_5 %uint_1 %56 %11 %uint_64 %uint_3 %62
- %64 = OpExtInst %void %1 DebugTypeComposite %13 %uint_0 %55 %uint_0 %uint_0 %56 %14 %51 %uint_3
- %67 = OpExtInst %void %1 DebugTypeFunction %uint_3 %57 %61
- %68 = OpExtInst %void %1 DebugFunction %16 %67 %55 %uint_15 %uint_1 %56 %16 %uint_3 %uint_16
- %69 = OpExtInst %void %1 DebugLexicalBlock %55 %uint_16 %uint_1 %68
- %70 = OpExtInst %void %1 DebugLocalVariable %17 %63 %55 %uint_19 %uint_12 %69 %uint_4
- %71 = OpExtInst %void %1 DebugLocalVariable %18 %57 %55 %uint_17 %uint_15 %69 %uint_4
- %72 = OpExtInst %void %1 DebugLocalVariable %19 %61 %55 %uint_15 %uint_29 %68 %uint_4 %uint_1
- %73 = OpExtInst %void %1 DebugTypeComposite %20 %uint_1 %55 %uint_0 %uint_0 %56 %21 %51 %uint_3
- %74 = OpExtInst %void %1 DebugGlobalVariable %22 %73 %55 %uint_3 %uint_14 %56 %22 %g_sAniso %uint_8
- %75 = OpExtInst %void %1 DebugGlobalVariable %23 %64 %55 %uint_1 %uint_11 %56 %23 %g_tColor %uint_8
- %MainPs = OpFunction %void None %45
- %76 = OpLabel
- %78 = OpVariable %_ptr_Function_PS_OUTPUT Function
- %79 = OpVariable %_ptr_Function_v2float Function
- %81 = OpVariable %_ptr_Function_PS_OUTPUT Function
- %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
- %82 = OpLoad %v2float %in_var_TEXCOORD2
- %83 = OpCompositeConstruct %PS_INPUT %82
- OpStore %param_var_i %83
- %112 = OpExtInst %void %1 DebugFunctionDefinition %68 %MainPs
- %109 = OpExtInst %void %1 DebugScope %68
- %85 = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
- %110 = OpExtInst %void %1 DebugScope %69
- %87 = OpExtInst %void %1 DebugDeclare %71 %78 %52
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugFunctionDefinition %68 %MainPs
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugScope %68
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugScope %69
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugDeclare %71 %78 %52
- %300 = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_17 %uint_30
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_17 %uint_30
- %88 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
- %89 = OpLoad %v2float %88
- %301 = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_12 %uint_35
- OpStore %79 %89
- ;CHECK-NOT: OpStore %79 %89
- %302 = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_12 %uint_35
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_12 %uint_35
- %106 = OpExtInst %void %1 DebugValue %70 %89 %52
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugValue %70 %89 %52
- %303 = OpExtInst %void %1 DebugLine %55 %uint_20 %uint_20 %uint_25 %uint_32
- %91 = OpLoad %type_2d_image %g_tColor
- %304 = OpExtInst %void %1 DebugLine %55 %uint_20 %uint_20 %uint_41 %uint_48
- %92 = OpLoad %type_sampler %g_sAniso
- %305 = OpExtInst %void %1 DebugLine %55 %uint_20 %uint_20 %uint_25 %uint_53
- %94 = OpSampledImage %type_sampled_image %91 %92
- %95 = OpImageSampleImplicitLod %v4float %94 %89 None
- %306 = OpExtInst %void %1 DebugLine %55 %uint_20 %uint_20 %uint_5 %uint_53
- %96 = OpAccessChain %_ptr_Function_v4float %78 %int_0
- OpStore %96 %95
- %307 = OpExtInst %void %1 DebugLine %55 %uint_21 %uint_21 %uint_12 %uint_20
- %97 = OpLoad %PS_OUTPUT %78
- %308 = OpExtInst %void %1 DebugLine %55 %uint_21 %uint_21 %uint_5 %uint_20
- OpStore %81 %97
- %309 = OpExtInst %void %1 DebugNoLine
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugNoLine
- %111 = OpExtInst %void %1 DebugNoScope
- ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugNoScope
- %100 = OpCompositeExtract %v4float %97 0
- OpStore %out_var_SV_Target0 %100
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, ShaderDebugInfoGlobalDCE) {
- // Verify that DebugGlobalVariable for eliminated private variable has
- // variable operand replaced with DebugInfoNone.
- const std::string text = R"(OpCapability Shader
- OpExtension "SPV_KHR_non_semantic_info"
- %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %MainPs "MainPs" %out_var_SV_Target0 %a
- OpExecutionMode %MainPs OriginUpperLeft
- %5 = OpString "source2.hlsl"
- %24 = OpString "float"
- %29 = OpString "vColor"
- %33 = OpString "PS_OUTPUT"
- %37 = OpString "MainPs"
- %38 = OpString ""
- %42 = OpString "ps_output"
- %46 = OpString "a"
- OpName %a "a"
- OpName %out_var_SV_Target0 "out.var.SV_Target0"
- OpName %MainPs "MainPs"
- OpName %PS_OUTPUT "PS_OUTPUT"
- OpMemberName %PS_OUTPUT 0 "vColor"
- OpDecorate %out_var_SV_Target0 Location 0
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %8 = OpConstantNull %v4float
- %float_0 = OpConstant %float 0
- %10 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %uint = OpTypeInt 32 0
- %uint_32 = OpConstant %uint 32
- %_ptr_Private_v4float = OpTypePointer Private %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %uint_1 = OpConstant %uint 1
- %uint_4 = OpConstant %uint 4
- %uint_5 = OpConstant %uint 5
- %uint_3 = OpConstant %uint 3
- %uint_0 = OpConstant %uint 0
- %uint_128 = OpConstant %uint 128
- %uint_12 = OpConstant %uint 12
- %uint_8 = OpConstant %uint 8
- %uint_9 = OpConstant %uint 9
- %uint_10 = OpConstant %uint 10
- %uint_15 = OpConstant %uint 15
- %48 = OpTypeFunction %void
- %PS_OUTPUT = OpTypeStruct %v4float
- %54 = OpTypeFunction %PS_OUTPUT
- %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %a = OpVariable %_ptr_Private_v4float Private
- ;CHECK-NOT: %a = OpVariable %_ptr_Private_v4float Private
- %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
- ;CHECK: [[dbg_none:%\w+]] = OpExtInst %void %1 DebugInfoNone
- %18 = OpExtInst %void %1 DebugExpression
- %19 = OpExtInst %void %1 DebugSource %5
- %20 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %19 %uint_5
- %25 = OpExtInst %void %1 DebugTypeBasic %24 %uint_32 %uint_3 %uint_0
- %28 = OpExtInst %void %1 DebugTypeVector %25 %uint_4
- %31 = OpExtInst %void %1 DebugTypeMember %29 %28 %19 %uint_5 %uint_12 %uint_0 %uint_128 %uint_3
- %34 = OpExtInst %void %1 DebugTypeComposite %33 %uint_1 %19 %uint_3 %uint_8 %20 %33 %uint_128 %uint_3 %31
- %36 = OpExtInst %void %1 DebugTypeFunction %uint_3 %34
- %39 = OpExtInst %void %1 DebugFunction %37 %36 %19 %uint_8 %uint_1 %20 %38 %uint_3 %uint_9
- %41 = OpExtInst %void %1 DebugLexicalBlock %19 %uint_9 %uint_1 %39
- %43 = OpExtInst %void %1 DebugLocalVariable %42 %34 %19 %uint_10 %uint_15 %41 %uint_4
- %47 = OpExtInst %void %1 DebugGlobalVariable %46 %28 %19 %uint_1 %uint_15 %20 %46 %a %uint_8
- ;CHECK: %47 = OpExtInst %void %1 DebugGlobalVariable %46 %28 %19 %uint_1 %uint_15 %20 %46 [[dbg_none]] %uint_8
- %MainPs = OpFunction %void None %48
- %49 = OpLabel
- %65 = OpVariable %_ptr_Function_PS_OUTPUT Function
- %66 = OpVariable %_ptr_Function_PS_OUTPUT Function
- OpStore %a %8
- %72 = OpExtInst %void %1 DebugScope %41
- %69 = OpExtInst %void %1 DebugDeclare %43 %65 %18
- OpLine %5 11 5
- %70 = OpAccessChain %_ptr_Function_v4float %65 %int_0
- OpStore %70 %10
- OpLine %5 12 12
- %71 = OpLoad %PS_OUTPUT %65
- OpLine %5 12 5
- OpStore %66 %71
- %73 = OpExtInst %void %1 DebugNoLine
- %74 = OpExtInst %void %1 DebugNoScope
- %51 = OpLoad %PS_OUTPUT %66
- %53 = OpCompositeExtract %v4float %51 0
- OpStore %out_var_SV_Target0 %53
- OpLine %5 13 1
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, DebugInfoDeclareKeepsStore) {
- // Verify that local variable tc and its store are kept by DebugDeclare.
- //
- // Same shader source as DebugInfoInFunctionKeepStoreVarElim. The SPIR-V
- // has just been inlined.
- const std::string text = R"(
- OpCapability Shader
- %1 = OpExtInstImport "OpenCL.DebugInfo.100"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_sAniso %in_var_TEXCOORD2 %out_var_SV_Target0
- OpExecutionMode %MainPs OriginUpperLeft
- %20 = OpString "foo.frag"
- %24 = OpString "PS_OUTPUT"
- %28 = OpString "float"
- %31 = OpString "vColor"
- %33 = OpString "PS_INPUT"
- %38 = OpString "vTextureCoords"
- %40 = OpString "@type.2d.image"
- %41 = OpString "type.2d.image"
- %43 = OpString "Texture2D.TemplateParam"
- %47 = OpString "src.MainPs"
- %51 = OpString "tc"
- %53 = OpString "ps_output"
- %56 = OpString "i"
- %58 = OpString "@type.sampler"
- %59 = OpString "type.sampler"
- %61 = OpString "g_sAniso"
- %63 = OpString "g_tColor"
- OpName %type_2d_image "type.2d.image"
- OpName %g_tColor "g_tColor"
- OpName %type_sampler "type.sampler"
- OpName %g_sAniso "g_sAniso"
- OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
- OpName %out_var_SV_Target0 "out.var.SV_Target0"
- OpName %MainPs "MainPs"
- OpName %PS_INPUT "PS_INPUT"
- OpMemberName %PS_INPUT 0 "vTextureCoords"
- OpName %param_var_i "param.var.i"
- OpName %PS_OUTPUT "PS_OUTPUT"
- OpMemberName %PS_OUTPUT 0 "vColor"
- OpName %type_sampled_image "type.sampled.image"
- OpDecorate %in_var_TEXCOORD2 Location 0
- OpDecorate %out_var_SV_Target0 Location 0
- OpDecorate %g_tColor DescriptorSet 0
- OpDecorate %g_tColor Binding 0
- OpDecorate %g_sAniso DescriptorSet 0
- OpDecorate %g_sAniso Binding 1
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %uint = OpTypeInt 32 0
- %uint_32 = OpConstant %uint 32
- %float = OpTypeFloat 32
- %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
- %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
- %type_sampler = OpTypeSampler
- %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
- %v2float = OpTypeVector %float 2
- %_ptr_Input_v2float = OpTypePointer Input %v2float
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %uint_128 = OpConstant %uint 128
- %uint_0 = OpConstant %uint 0
- %uint_64 = OpConstant %uint 64
- %65 = OpTypeFunction %void
- %PS_INPUT = OpTypeStruct %v2float
- %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
- %PS_OUTPUT = OpTypeStruct %v4float
- %75 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
- %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
- %_ptr_Function_v2float = OpTypePointer Function %v2float
- %type_sampled_image = OpTypeSampledImage %type_2d_image
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
- %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
- %in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
- %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
- %39 = OpExtInst %void %1 DebugInfoNone
- %55 = OpExtInst %void %1 DebugExpression
- %22 = OpExtInst %void %1 DebugSource %20
- %23 = OpExtInst %void %1 DebugCompilationUnit 1 4 %22 HLSL
- %26 = OpExtInst %void %1 DebugTypeComposite %24 Structure %22 10 1 %23 %24 %uint_128 FlagIsProtected|FlagIsPrivate %27
- %29 = OpExtInst %void %1 DebugTypeBasic %28 %uint_32 Float
- %30 = OpExtInst %void %1 DebugTypeVector %29 4
- %27 = OpExtInst %void %1 DebugTypeMember %31 %30 %22 12 5 %26 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
- %35 = OpExtInst %void %1 DebugTypeComposite %33 Structure %22 5 1 %23 %33 %uint_64 FlagIsProtected|FlagIsPrivate %36
- %37 = OpExtInst %void %1 DebugTypeVector %29 2
- %36 = OpExtInst %void %1 DebugTypeMember %38 %37 %22 7 5 %35 %uint_0 %uint_64 FlagIsProtected|FlagIsPrivate
- %42 = OpExtInst %void %1 DebugTypeComposite %40 Class %22 0 0 %23 %41 %39 FlagIsProtected|FlagIsPrivate
- %44 = OpExtInst %void %1 DebugTypeTemplateParameter %43 %29 %39 %22 0 0
- %45 = OpExtInst %void %1 DebugTypeTemplate %42 %44
- %46 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %26 %35
- %48 = OpExtInst %void %1 DebugFunction %47 %46 %22 15 1 %23 %47 FlagIsProtected|FlagIsPrivate 16 %39
- %50 = OpExtInst %void %1 DebugLexicalBlock %22 16 1 %48
- %52 = OpExtInst %void %1 DebugLocalVariable %51 %37 %22 19 12 %50 FlagIsLocal
- %54 = OpExtInst %void %1 DebugLocalVariable %53 %26 %22 17 15 %50 FlagIsLocal
- %57 = OpExtInst %void %1 DebugLocalVariable %56 %35 %22 15 29 %48 FlagIsLocal 1
- %60 = OpExtInst %void %1 DebugTypeComposite %58 Structure %22 0 0 %23 %59 %39 FlagIsProtected|FlagIsPrivate
- %62 = OpExtInst %void %1 DebugGlobalVariable %61 %60 %22 3 14 %23 %61 %g_sAniso FlagIsDefinition
- %64 = OpExtInst %void %1 DebugGlobalVariable %63 %42 %22 1 11 %23 %63 %g_tColor FlagIsDefinition
- %MainPs = OpFunction %void None %65
- %66 = OpLabel
- %114 = OpExtInst %void %1 DebugScope %50
- %98 = OpVariable %_ptr_Function_PS_OUTPUT Function
- %99 = OpVariable %_ptr_Function_v2float Function
- %115 = OpExtInst %void %1 DebugNoScope
- %100 = OpVariable %_ptr_Function_PS_OUTPUT Function
- %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
- %70 = OpLoad %v2float %in_var_TEXCOORD2
- %71 = OpCompositeConstruct %PS_INPUT %70
- OpStore %param_var_i %71
- %116 = OpExtInst %void %1 DebugScope %48
- %102 = OpExtInst %void %1 DebugDeclare %57 %param_var_i %55
- %117 = OpExtInst %void %1 DebugScope %50
- %103 = OpExtInst %void %1 DebugDeclare %54 %98 %55
- OpLine %20 19 17
- %104 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
- %105 = OpLoad %v2float %104
- OpLine %20 19 12
- OpStore %99 %105
- ;CHECK: OpStore %99 %105
- %106 = OpExtInst %void %1 DebugDeclare %52 %99 %55
- OpLine %20 20 26
- %107 = OpLoad %type_2d_image %g_tColor
- OpLine %20 20 46
- %108 = OpLoad %type_sampler %g_sAniso
- OpLine %20 20 26
- %110 = OpSampledImage %type_sampled_image %107 %108
- %111 = OpImageSampleImplicitLod %v4float %110 %105 None
- OpLine %20 20 5
- %112 = OpAccessChain %_ptr_Function_v4float %98 %int_0
- OpStore %112 %111
- OpLine %20 21 12
- %113 = OpLoad %PS_OUTPUT %98
- OpLine %20 21 5
- OpStore %100 %113
- %118 = OpExtInst %void %1 DebugNoScope
- %73 = OpLoad %PS_OUTPUT %100
- %74 = OpCompositeExtract %v4float %73 0
- OpStore %out_var_SV_Target0 %74
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, DebugInfoValueDerefKeepsStore) {
- // Verify that local variable tc and its store are kept by DebugValue with
- // Deref.
- //
- // Same shader source as DebugInfoInFunctionKeepStoreVarElim. The SPIR-V
- // has just been inlined and edited to replace the DebugDeclare with the
- // DebugValue/Deref.
- const std::string text = R"(
- OpCapability Shader
- %1 = OpExtInstImport "OpenCL.DebugInfo.100"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_sAniso %in_var_TEXCOORD2 %out_var_SV_Target0
- OpExecutionMode %MainPs OriginUpperLeft
- %7 = OpString "foo.frag"
- %8 = OpString "PS_OUTPUT"
- %9 = OpString "float"
- %10 = OpString "vColor"
- %11 = OpString "PS_INPUT"
- %12 = OpString "vTextureCoords"
- %13 = OpString "@type.2d.image"
- %14 = OpString "type.2d.image"
- %15 = OpString "Texture2D.TemplateParam"
- %16 = OpString "src.MainPs"
- %17 = OpString "tc"
- %18 = OpString "ps_output"
- %19 = OpString "i"
- %20 = OpString "@type.sampler"
- %21 = OpString "type.sampler"
- %22 = OpString "g_sAniso"
- %23 = OpString "g_tColor"
- OpName %type_2d_image "type.2d.image"
- OpName %g_tColor "g_tColor"
- OpName %type_sampler "type.sampler"
- OpName %g_sAniso "g_sAniso"
- OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
- OpName %out_var_SV_Target0 "out.var.SV_Target0"
- OpName %MainPs "MainPs"
- OpName %PS_INPUT "PS_INPUT"
- OpMemberName %PS_INPUT 0 "vTextureCoords"
- OpName %param_var_i "param.var.i"
- OpName %PS_OUTPUT "PS_OUTPUT"
- OpMemberName %PS_OUTPUT 0 "vColor"
- OpName %type_sampled_image "type.sampled.image"
- OpDecorate %in_var_TEXCOORD2 Location 0
- OpDecorate %out_var_SV_Target0 Location 0
- OpDecorate %g_tColor DescriptorSet 0
- OpDecorate %g_tColor Binding 0
- OpDecorate %g_sAniso DescriptorSet 0
- OpDecorate %g_sAniso Binding 1
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %uint = OpTypeInt 32 0
- %uint_32 = OpConstant %uint 32
- %float = OpTypeFloat 32
- %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
- %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
- %type_sampler = OpTypeSampler
- %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
- %v2float = OpTypeVector %float 2
- %_ptr_Input_v2float = OpTypePointer Input %v2float
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %uint_128 = OpConstant %uint 128
- %uint_0 = OpConstant %uint 0
- %uint_64 = OpConstant %uint 64
- %45 = OpTypeFunction %void
- %PS_INPUT = OpTypeStruct %v2float
- %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
- %PS_OUTPUT = OpTypeStruct %v4float
- %47 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
- %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
- %_ptr_Function_v2float = OpTypePointer Function %v2float
- %type_sampled_image = OpTypeSampledImage %type_2d_image
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
- %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
- %in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
- %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
- %51 = OpExtInst %void %1 DebugInfoNone
- %52 = OpExtInst %void %1 DebugExpression
- %53 = OpExtInst %void %1 DebugOperation Deref
- %54 = OpExtInst %void %1 DebugExpression %53
- %55 = OpExtInst %void %1 DebugSource %7
- %56 = OpExtInst %void %1 DebugCompilationUnit 1 4 %55 HLSL
- %57 = OpExtInst %void %1 DebugTypeComposite %8 Structure %55 10 1 %56 %8 %uint_128 FlagIsProtected|FlagIsPrivate %58
- %59 = OpExtInst %void %1 DebugTypeBasic %9 %uint_32 Float
- %60 = OpExtInst %void %1 DebugTypeVector %59 4
- %58 = OpExtInst %void %1 DebugTypeMember %10 %60 %55 12 5 %57 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
- %61 = OpExtInst %void %1 DebugTypeComposite %11 Structure %55 5 1 %56 %11 %uint_64 FlagIsProtected|FlagIsPrivate %62
- %63 = OpExtInst %void %1 DebugTypeVector %59 2
- %62 = OpExtInst %void %1 DebugTypeMember %12 %63 %55 7 5 %61 %uint_0 %uint_64 FlagIsProtected|FlagIsPrivate
- %64 = OpExtInst %void %1 DebugTypeComposite %13 Class %55 0 0 %56 %14 %51 FlagIsProtected|FlagIsPrivate
- %65 = OpExtInst %void %1 DebugTypeTemplateParameter %15 %59 %51 %55 0 0
- %66 = OpExtInst %void %1 DebugTypeTemplate %64 %65
- %67 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %57 %61
- %68 = OpExtInst %void %1 DebugFunction %16 %67 %55 15 1 %56 %16 FlagIsProtected|FlagIsPrivate 16 %51
- %69 = OpExtInst %void %1 DebugLexicalBlock %55 16 1 %68
- %70 = OpExtInst %void %1 DebugLocalVariable %17 %63 %55 19 12 %69 FlagIsLocal
- %71 = OpExtInst %void %1 DebugLocalVariable %18 %57 %55 17 15 %69 FlagIsLocal
- %72 = OpExtInst %void %1 DebugLocalVariable %19 %61 %55 15 29 %68 FlagIsLocal 1
- %73 = OpExtInst %void %1 DebugTypeComposite %20 Structure %55 0 0 %56 %21 %51 FlagIsProtected|FlagIsPrivate
- %74 = OpExtInst %void %1 DebugGlobalVariable %22 %73 %55 3 14 %56 %22 %g_sAniso FlagIsDefinition
- %75 = OpExtInst %void %1 DebugGlobalVariable %23 %64 %55 1 11 %56 %23 %g_tColor FlagIsDefinition
- %MainPs = OpFunction %void None %45
- %76 = OpLabel
- %101 = OpExtInst %void %1 DebugScope %69
- %78 = OpVariable %_ptr_Function_PS_OUTPUT Function
- %79 = OpVariable %_ptr_Function_v2float Function
- %102 = OpExtInst %void %1 DebugNoScope
- %81 = OpVariable %_ptr_Function_PS_OUTPUT Function
- %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
- %82 = OpLoad %v2float %in_var_TEXCOORD2
- %83 = OpCompositeConstruct %PS_INPUT %82
- OpStore %param_var_i %83
- %103 = OpExtInst %void %1 DebugScope %68
- %85 = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
- %104 = OpExtInst %void %1 DebugScope %69
- %87 = OpExtInst %void %1 DebugDeclare %71 %78 %52
- OpLine %7 19 17
- %88 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
- %89 = OpLoad %v2float %88
- OpLine %7 19 12
- OpStore %79 %89
- ;CHECK: OpStore %79 %89
- %90 = OpExtInst %void %1 DebugValue %70 %79 %54
- OpLine %7 20 26
- %91 = OpLoad %type_2d_image %g_tColor
- OpLine %7 20 46
- %92 = OpLoad %type_sampler %g_sAniso
- OpLine %7 20 26
- %94 = OpSampledImage %type_sampled_image %91 %92
- %95 = OpImageSampleImplicitLod %v4float %94 %89 None
- OpLine %7 20 5
- %96 = OpAccessChain %_ptr_Function_v4float %78 %int_0
- OpStore %96 %95
- OpLine %7 21 12
- %97 = OpLoad %PS_OUTPUT %78
- OpLine %7 21 5
- OpStore %81 %97
- %105 = OpExtInst %void %1 DebugNoScope
- %99 = OpLoad %PS_OUTPUT %81
- %100 = OpCompositeExtract %v4float %99 0
- OpStore %out_var_SV_Target0 %100
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, DebugInfoElimUnusedTextureKeepGlobalVariable) {
- // Verify that unused texture g_tColor2 is eliminated but its
- // DebugGlobalVariable is retained but with DebugInfoNone for its Variable.
- //
- // Same shader source as DebugInfoInFunctionKeepStoreVarElim but with unused
- // g_tColor2 added.
- const std::string text = R"(
- OpCapability Shader
- %1 = OpExtInstImport "OpenCL.DebugInfo.100"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_tColor2 %g_sAniso %in_var_TEXCOORD2 %out_var_SV_Target0
- OpExecutionMode %MainPs OriginUpperLeft
- %21 = OpString "foo6.frag"
- %25 = OpString "PS_OUTPUT"
- %29 = OpString "float"
- %32 = OpString "vColor"
- %34 = OpString "PS_INPUT"
- %39 = OpString "vTextureCoords"
- %41 = OpString "@type.2d.image"
- %42 = OpString "type.2d.image"
- %44 = OpString "Texture2D.TemplateParam"
- %48 = OpString "src.MainPs"
- %52 = OpString "tc"
- %54 = OpString "ps_output"
- %57 = OpString "i"
- %59 = OpString "@type.sampler"
- %60 = OpString "type.sampler"
- %62 = OpString "g_sAniso"
- %64 = OpString "g_tColor2"
- %66 = OpString "g_tColor"
- OpName %type_2d_image "type.2d.image"
- OpName %g_tColor "g_tColor"
- OpName %g_tColor2 "g_tColor2"
- OpName %type_sampler "type.sampler"
- OpName %g_sAniso "g_sAniso"
- OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
- OpName %out_var_SV_Target0 "out.var.SV_Target0"
- OpName %MainPs "MainPs"
- OpName %PS_INPUT "PS_INPUT"
- OpMemberName %PS_INPUT 0 "vTextureCoords"
- OpName %param_var_i "param.var.i"
- OpName %PS_OUTPUT "PS_OUTPUT"
- OpMemberName %PS_OUTPUT 0 "vColor"
- OpName %type_sampled_image "type.sampled.image"
- OpDecorate %in_var_TEXCOORD2 Location 0
- OpDecorate %out_var_SV_Target0 Location 0
- OpDecorate %g_tColor DescriptorSet 0
- OpDecorate %g_tColor Binding 0
- OpDecorate %g_tColor2 DescriptorSet 0
- OpDecorate %g_tColor2 Binding 1
- OpDecorate %g_sAniso DescriptorSet 0
- OpDecorate %g_sAniso Binding 2
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %uint = OpTypeInt 32 0
- %uint_32 = OpConstant %uint 32
- %float = OpTypeFloat 32
- %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
- %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
- %type_sampler = OpTypeSampler
- %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
- %v2float = OpTypeVector %float 2
- %_ptr_Input_v2float = OpTypePointer Input %v2float
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %uint_128 = OpConstant %uint 128
- %uint_0 = OpConstant %uint 0
- %uint_64 = OpConstant %uint 64
- %68 = OpTypeFunction %void
- %PS_INPUT = OpTypeStruct %v2float
- %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
- %PS_OUTPUT = OpTypeStruct %v4float
- %78 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
- %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
- %_ptr_Function_v2float = OpTypePointer Function %v2float
- %type_sampled_image = OpTypeSampledImage %type_2d_image
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
- %g_tColor2 = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
- ;CHECK-NOT: %g_tColor2 = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
- %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
- %in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
- %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
- %40 = OpExtInst %void %1 DebugInfoNone
- %56 = OpExtInst %void %1 DebugExpression
- %23 = OpExtInst %void %1 DebugSource %21
- %24 = OpExtInst %void %1 DebugCompilationUnit 1 4 %23 HLSL
- %27 = OpExtInst %void %1 DebugTypeComposite %25 Structure %23 11 1 %24 %25 %uint_128 FlagIsProtected|FlagIsPrivate %28
- %30 = OpExtInst %void %1 DebugTypeBasic %29 %uint_32 Float
- %31 = OpExtInst %void %1 DebugTypeVector %30 4
- %28 = OpExtInst %void %1 DebugTypeMember %32 %31 %23 13 5 %27 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
- %36 = OpExtInst %void %1 DebugTypeComposite %34 Structure %23 6 1 %24 %34 %uint_64 FlagIsProtected|FlagIsPrivate %37
- %38 = OpExtInst %void %1 DebugTypeVector %30 2
- %37 = OpExtInst %void %1 DebugTypeMember %39 %38 %23 8 5 %36 %uint_0 %uint_64 FlagIsProtected|FlagIsPrivate
- %43 = OpExtInst %void %1 DebugTypeComposite %41 Class %23 0 0 %24 %42 %40 FlagIsProtected|FlagIsPrivate
- %45 = OpExtInst %void %1 DebugTypeTemplateParameter %44 %30 %40 %23 0 0
- %46 = OpExtInst %void %1 DebugTypeTemplate %43 %45
- %47 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %27 %36
- %49 = OpExtInst %void %1 DebugFunction %48 %47 %23 16 1 %24 %48 FlagIsProtected|FlagIsPrivate 17 %40
- %51 = OpExtInst %void %1 DebugLexicalBlock %23 17 1 %49
- %53 = OpExtInst %void %1 DebugLocalVariable %52 %38 %23 20 12 %51 FlagIsLocal
- %55 = OpExtInst %void %1 DebugLocalVariable %54 %27 %23 18 15 %51 FlagIsLocal
- %58 = OpExtInst %void %1 DebugLocalVariable %57 %36 %23 16 29 %49 FlagIsLocal 1
- %61 = OpExtInst %void %1 DebugTypeComposite %59 Structure %23 0 0 %24 %60 %40 FlagIsProtected|FlagIsPrivate
- %63 = OpExtInst %void %1 DebugGlobalVariable %62 %61 %23 4 14 %24 %62 %g_sAniso FlagIsDefinition
- %65 = OpExtInst %void %1 DebugGlobalVariable %64 %43 %23 2 11 %24 %64 %g_tColor2 FlagIsDefinition
- ;CHECK-NOT: %65 = OpExtInst %void %1 DebugGlobalVariable %64 %43 %23 2 11 %24 %64 %g_tColor2 FlagIsDefinition
- ;CHECK: %65 = OpExtInst %void %1 DebugGlobalVariable %64 %43 %23 2 11 %24 %64 %40 FlagIsDefinition
- %67 = OpExtInst %void %1 DebugGlobalVariable %66 %43 %23 1 11 %24 %66 %g_tColor FlagIsDefinition
- %MainPs = OpFunction %void None %68
- %69 = OpLabel
- %117 = OpExtInst %void %1 DebugScope %51
- %101 = OpVariable %_ptr_Function_PS_OUTPUT Function
- %102 = OpVariable %_ptr_Function_v2float Function
- %118 = OpExtInst %void %1 DebugNoScope
- %103 = OpVariable %_ptr_Function_PS_OUTPUT Function
- %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
- %73 = OpLoad %v2float %in_var_TEXCOORD2
- %74 = OpCompositeConstruct %PS_INPUT %73
- OpStore %param_var_i %74
- %119 = OpExtInst %void %1 DebugScope %49
- %105 = OpExtInst %void %1 DebugDeclare %58 %param_var_i %56
- %120 = OpExtInst %void %1 DebugScope %51
- %106 = OpExtInst %void %1 DebugDeclare %55 %101 %56
- OpLine %21 20 17
- %107 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
- %108 = OpLoad %v2float %107
- OpLine %21 20 12
- OpStore %102 %108
- %109 = OpExtInst %void %1 DebugDeclare %53 %102 %56
- OpLine %21 21 26
- %110 = OpLoad %type_2d_image %g_tColor
- OpLine %21 21 46
- %111 = OpLoad %type_sampler %g_sAniso
- OpLine %21 21 57
- %112 = OpLoad %v2float %102
- OpLine %21 21 26
- %113 = OpSampledImage %type_sampled_image %110 %111
- %114 = OpImageSampleImplicitLod %v4float %113 %112 None
- OpLine %21 21 5
- %115 = OpAccessChain %_ptr_Function_v4float %101 %int_0
- OpStore %115 %114
- OpLine %21 22 12
- %116 = OpLoad %PS_OUTPUT %101
- OpLine %21 22 5
- OpStore %103 %116
- %121 = OpExtInst %void %1 DebugNoScope
- %76 = OpLoad %PS_OUTPUT %103
- %77 = OpCompositeExtract %v4float %76 0
- OpStore %out_var_SV_Target0 %77
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, KeepDebugScopeParent) {
- // Verify that local variable tc and its store are kept by DebugDeclare.
- //
- // Same shader source as DebugInfoInFunctionKeepStoreVarElim. The SPIR-V
- // has just been inlined.
- const std::string text = R"(
- OpCapability Shader
- %1 = OpExtInstImport "OpenCL.DebugInfo.100"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %out_var_SV_TARGET0
- OpExecutionMode %main OriginUpperLeft
- %11 = OpString "float"
- %16 = OpString "t.hlsl"
- %19 = OpString "src.main"
- OpName %out_var_SV_TARGET0 "out.var.SV_TARGET0"
- OpName %main "main"
- OpDecorate %out_var_SV_TARGET0 Location 0
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %v4float = OpTypeVector %float 4
- %7 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %uint = OpTypeInt 32 0
- %uint_32 = OpConstant %uint 32
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %23 = OpTypeFunction %void
- %26 = OpTypeFunction %v4float
- %out_var_SV_TARGET0 = OpVariable %_ptr_Output_v4float Output
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %33 = OpExtInst %void %1 DebugInfoNone
- %13 = OpExtInst %void %1 DebugTypeBasic %11 %uint_32 Float
- %14 = OpExtInst %void %1 DebugTypeVector %13 4
- %15 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %14
- %17 = OpExtInst %void %1 DebugSource %16
- %18 = OpExtInst %void %1 DebugCompilationUnit 1 4 %17 HLSL
- %20 = OpExtInst %void %1 DebugFunction %19 %15 %17 1 1 %18 %19 FlagIsProtected|FlagIsPrivate 2 %33
- %22 = OpExtInst %void %1 DebugLexicalBlock %17 2 1 %20
- %main = OpFunction %void None %23
- %24 = OpLabel
- %31 = OpVariable %_ptr_Function_v4float Function
- ; CHECK: [[block:%\w+]] = OpExtInst %void %1 DebugLexicalBlock
- ; CHECK: DebugScope [[block]]
- %34 = OpExtInst %void %1 DebugScope %22
- OpLine %16 3 5
- OpStore %31 %7
- OpStore %out_var_SV_TARGET0 %7
- %35 = OpExtInst %void %1 DebugNoScope
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, KeepExportFunctions) {
- // All functions are reachable. In particular, ExportedFunc and Constant are
- // reachable because ExportedFunc is exported. Nothing should be removed.
- const std::vector<const char*> text = {
- // clang-format off
- "OpCapability Shader",
- "OpCapability Linkage",
- "OpMemoryModel Logical GLSL450",
- "OpEntryPoint Fragment %main \"main\"",
- "OpName %main \"main\"",
- "OpName %ExportedFunc \"ExportedFunc\"",
- "OpName %Live \"Live\"",
- "OpDecorate %ExportedFunc LinkageAttributes \"ExportedFunc\" Export",
- "%void = OpTypeVoid",
- "%7 = OpTypeFunction %void",
- "%main = OpFunction %void None %7",
- "%15 = OpLabel",
- "OpReturn",
- "OpFunctionEnd",
- "%ExportedFunc = OpFunction %void None %7",
- "%19 = OpLabel",
- "%16 = OpFunctionCall %void %Live",
- "OpReturn",
- "OpFunctionEnd",
- "%Live = OpFunction %void None %7",
- "%20 = OpLabel",
- "OpReturn",
- "OpFunctionEnd"
- // clang-format on
- };
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- std::string assembly = JoinAllInsts(text);
- auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
- assembly, /* skip_nop = */ true, /* do_validation = */ false);
- EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
- EXPECT_EQ(assembly, std::get<0>(result));
- }
- TEST_F(AggressiveDCETest, KeepPrivateVarInExportFunctions) {
- // The loads and stores from the private variable should not be removed
- // because the functions are exported and could be called.
- const std::string text = R"(OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpSource HLSL 630
- OpName %privateVar "privateVar"
- OpName %ReadPrivate "ReadPrivate"
- OpName %WritePrivate "WritePrivate"
- OpName %value "value"
- OpDecorate %ReadPrivate LinkageAttributes "ReadPrivate" Export
- OpDecorate %WritePrivate LinkageAttributes "WritePrivate" Export
- %int = OpTypeInt 32 1
- %_ptr_Private_int = OpTypePointer Private %int
- %6 = OpTypeFunction %int
- %void = OpTypeVoid
- %_ptr_Function_int = OpTypePointer Function %int
- %10 = OpTypeFunction %void %_ptr_Function_int
- %privateVar = OpVariable %_ptr_Private_int Private
- %ReadPrivate = OpFunction %int None %6
- %12 = OpLabel
- %8 = OpLoad %int %privateVar
- OpReturnValue %8
- OpFunctionEnd
- %WritePrivate = OpFunction %void None %10
- %value = OpFunctionParameter %_ptr_Function_int
- %13 = OpLabel
- %14 = OpLoad %int %value
- OpStore %privateVar %14
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
- text, /* skip_nop = */ true, /* do_validation = */ false);
- EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
- EXPECT_EQ(text, std::get<0>(result));
- }
- TEST_F(AggressiveDCETest, KeepLableNames) {
- const std::string text = R"(OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpSource HLSL 630
- OpName %WritePrivate "WritePrivate"
- OpName %entry "entry"
- OpName %target "target"
- OpDecorate %WritePrivate LinkageAttributes "WritePrivate" Export
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %WritePrivate = OpFunction %void None %3
- %entry = OpLabel
- OpBranch %target
- %target = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
- text, /* skip_nop = */ true, /* do_validation = */ false);
- EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
- EXPECT_EQ(text, std::get<0>(result));
- }
- TEST_F(AggressiveDCETest, PreserveInterface) {
- // Set preserve_interface to true. Verify that unused uniform
- // constant in entry point interface is not eliminated.
- const std::string text = R"(OpCapability RayTracingKHR
- OpExtension "SPV_KHR_ray_tracing"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint RayGenerationKHR %2 "main" %3 %4
- OpDecorate %3 Location 0
- OpDecorate %4 DescriptorSet 2
- OpDecorate %4 Binding 0
- %void = OpTypeVoid
- %6 = OpTypeFunction %void
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %float = OpTypeFloat 32
- %_ptr_CallableDataKHR_float = OpTypePointer CallableDataKHR %float
- %3 = OpVariable %_ptr_CallableDataKHR_float CallableDataKHR
- %13 = OpTypeAccelerationStructureKHR
- %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
- %4 = OpVariable %_ptr_UniformConstant_13 UniformConstant
- %2 = OpFunction %void None %6
- %15 = OpLabel
- OpExecuteCallableKHR %uint_0 %3
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
- text, /* skip_nop = */ true, /* do_validation = */ false,
- /* preserve_interface */ true);
- EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
- EXPECT_EQ(text, std::get<0>(result));
- }
- TEST_F(AggressiveDCETest, EmptyContinueWithConditionalBranch) {
- const std::string text = R"(OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %2 "main"
- OpExecutionMode %2 OriginUpperLeft
- %void = OpTypeVoid
- %4 = OpTypeFunction %void
- %bool = OpTypeBool
- %false = OpConstantFalse %bool
- %2 = OpFunction %void None %4
- %9 = OpLabel
- OpBranch %10
- %10 = OpLabel
- OpLoopMerge %11 %12 None
- OpBranch %13
- %13 = OpLabel
- OpKill
- %12 = OpLabel
- OpBranchConditional %false %10 %10
- %11 = OpLabel
- OpUnreachable
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(text, text, false);
- }
- TEST_F(AggressiveDCETest, FunctionBecomesUnreachableAfterDCE) {
- const std::string text = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %2 "main"
- OpExecutionMode %2 OriginUpperLeft
- OpSource ESSL 320
- %void = OpTypeVoid
- %4 = OpTypeFunction %void
- %int = OpTypeInt 32 1
- %_ptr_Function_int = OpTypePointer Function %int
- %7 = OpTypeFunction %int
- %int_n1 = OpConstant %int -1
- %2 = OpFunction %void None %4
- %9 = OpLabel
- OpKill
- %10 = OpLabel
- %11 = OpFunctionCall %int %12
- OpReturn
- OpFunctionEnd
- ; CHECK: {{%\w+}} = OpFunction %int DontInline|Pure
- %12 = OpFunction %int DontInline|Pure %7
- ; CHECK-NEXT: {{%\w+}} = OpLabel
- %13 = OpLabel
- %14 = OpVariable %_ptr_Function_int Function
- ; CHECK-NEXT: OpBranch [[header:%\w+]]
- OpBranch %15
- ; CHECK-NEXT: [[header]] = OpLabel
- ; CHECK-NEXT: OpBranch [[merge:%\w+]]
- %15 = OpLabel
- OpLoopMerge %16 %17 None
- OpBranch %18
- %18 = OpLabel
- %19 = OpLoad %int %14
- OpBranch %17
- %17 = OpLabel
- OpBranch %15
- ; CHECK-NEXT: [[merge]] = OpLabel
- %16 = OpLabel
- ; CHECK-NEXT: OpReturnValue %int_n1
- OpReturnValue %int_n1
- ; CHECK-NEXT: OpFunctionEnd
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, KeepTopLevelDebugInfo) {
- // Don't eliminate DebugCompilationUnit, DebugSourceContinued, and
- // DebugEntryPoint
- const std::string text = R"(
- OpCapability Shader
- OpExtension "SPV_KHR_non_semantic_info"
- %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %MainPs "MainPs" %out_var_SV_Target0
- OpExecutionMode %MainPs OriginUpperLeft
- %4 = OpString "foo2.frag"
- %5 = OpString "
- struct PS_OUTPUT
- {
- float4 vColor : SV_Target0 ;
- } ;
- "
- %6 = OpString "
- PS_OUTPUT MainPs ( )
- {
- PS_OUTPUT ps_output ;
- ps_output . vColor = float4( 1.0, 0.0, 0.0, 0.0 );
- return ps_output ;
- }
- "
- %7 = OpString "float"
- %8 = OpString "vColor"
- %9 = OpString "PS_OUTPUT"
- %10 = OpString "MainPs"
- %11 = OpString ""
- %12 = OpString "ps_output"
- %13 = OpString "97a939fb"
- %14 = OpString " foo2.frag -E MainPs -T ps_6_1 -spirv -fspv-target-env=vulkan1.2 -fspv-debug=vulkan-with-source -fcgl -Fo foo2.frag.nopt.spv -Qembed_debug"
- OpName %out_var_SV_Target0 "out.var.SV_Target0"
- OpName %MainPs "MainPs"
- OpDecorate %out_var_SV_Target0 Location 0
- %float = OpTypeFloat 32
- %float_1 = OpConstant %float 1
- %float_0 = OpConstant %float 0
- %v4float = OpTypeVector %float 4
- %23 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_0
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %uint = OpTypeInt 32 0
- %uint_32 = OpConstant %uint 32
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %uint_1 = OpConstant %uint 1
- %uint_4 = OpConstant %uint 4
- %uint_5 = OpConstant %uint 5
- %uint_3 = OpConstant %uint 3
- %uint_0 = OpConstant %uint 0
- %uint_128 = OpConstant %uint 128
- %uint_12 = OpConstant %uint 12
- %uint_2 = OpConstant %uint 2
- %uint_8 = OpConstant %uint 8
- %uint_7 = OpConstant %uint 7
- %uint_9 = OpConstant %uint 9
- %uint_15 = OpConstant %uint 15
- %42 = OpTypeFunction %void
- %uint_10 = OpConstant %uint 10
- %uint_53 = OpConstant %uint 53
- %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
- %49 = OpExtInst %void %1 DebugExpression
- %50 = OpExtInst %void %1 DebugSource %4 %5
- %51 = OpExtInst %void %1 DebugSourceContinued %6
- ; CHECK: %51 = OpExtInst %void %1 DebugSourceContinued %6
- %52 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %50 %uint_5
- ; CHECK: %52 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %50 %uint_5
- %53 = OpExtInst %void %1 DebugTypeBasic %7 %uint_32 %uint_3 %uint_0
- %54 = OpExtInst %void %1 DebugTypeVector %53 %uint_4
- %55 = OpExtInst %void %1 DebugTypeMember %8 %54 %50 %uint_4 %uint_12 %uint_0 %uint_128 %uint_3
- %56 = OpExtInst %void %1 DebugTypeComposite %9 %uint_1 %50 %uint_2 %uint_8 %52 %9 %uint_128 %uint_3 %55
- %57 = OpExtInst %void %1 DebugTypeFunction %uint_3 %56
- %58 = OpExtInst %void %1 DebugFunction %10 %57 %50 %uint_7 %uint_1 %52 %11 %uint_3 %uint_8
- %59 = OpExtInst %void %1 DebugLexicalBlock %50 %uint_8 %uint_1 %58
- %60 = OpExtInst %void %1 DebugLocalVariable %12 %56 %50 %uint_9 %uint_15 %59 %uint_4
- %61 = OpExtInst %void %1 DebugEntryPoint %58 %52 %13 %14
- ; CHECK: %61 = OpExtInst %void %1 DebugEntryPoint %58 %52 %13 %14
- %MainPs = OpFunction %void None %42
- %62 = OpLabel
- %63 = OpExtInst %void %1 DebugFunctionDefinition %58 %MainPs
- %112 = OpExtInst %void %1 DebugScope %59
- %111 = OpExtInst %void %1 DebugLine %50 %uint_10 %uint_10 %uint_5 %uint_53
- %110 = OpExtInst %void %1 DebugValue %60 %23 %49 %int_0
- %113 = OpExtInst %void %1 DebugNoLine
- %114 = OpExtInst %void %1 DebugNoScope
- OpStore %out_var_SV_Target0 %23
- %66 = OpExtInst %void %1 DebugLine %50 %uint_12 %uint_12 %uint_1 %uint_1
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, RemoveOutputTrue) {
- // Remove dead n_out output variable from module
- const std::string text = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %c_out %c_in %n_out
- ;CHECK: OpEntryPoint Vertex %main "main" %c_out %c_in
- OpSource GLSL 450
- OpName %main "main"
- OpName %c_out "c_out"
- OpName %c_in "c_in"
- OpName %n_out "n_out"
- OpDecorate %c_out Location 0
- OpDecorate %c_in Location 0
- OpDecorate %n_out Location 1
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %c_out = OpVariable %_ptr_Output_v4float Output
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %c_in = OpVariable %_ptr_Input_v4float Input
- %v3float = OpTypeVector %float 3
- %_ptr_Output_v3float = OpTypePointer Output %v3float
- %n_out = OpVariable %_ptr_Output_v3float Output
- %main = OpFunction %void None %3
- %5 = OpLabel
- %12 = OpLoad %v4float %c_in
- OpStore %c_out %12
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_VULKAN_1_3);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true, false, true);
- }
- TEST_F(AggressiveDCETest, RemoveOutputFalse) {
- // Remove dead n_out output variable from module
- const std::string text = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %c_out %c_in %n_out
- ;CHECK: OpEntryPoint Vertex %main "main" %c_out %c_in %n_out
- OpSource GLSL 450
- OpName %main "main"
- OpName %c_out "c_out"
- OpName %c_in "c_in"
- OpName %n_out "n_out"
- OpDecorate %c_out Location 0
- OpDecorate %c_in Location 0
- OpDecorate %n_out Location 1
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %c_out = OpVariable %_ptr_Output_v4float Output
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %c_in = OpVariable %_ptr_Input_v4float Input
- %v3float = OpTypeVector %float 3
- %_ptr_Output_v3float = OpTypePointer Output %v3float
- %n_out = OpVariable %_ptr_Output_v3float Output
- %main = OpFunction %void None %3
- %5 = OpLabel
- %12 = OpLoad %v4float %c_in
- OpStore %c_out %12
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_VULKAN_1_3);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true, false, false);
- }
- TEST_F(AggressiveDCETest, RemoveWhenUsingPrintfExtension) {
- // Remove dead n_out output variable from module
- const std::string text = R"(
- ; CHECK: OpExtInstImport "NonSemantic.DebugPrintf"
- ; CHECK-NOT: OpVariable
- OpCapability Shader
- %1 = OpExtInstImport "NonSemantic.DebugPrintf"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %main "main"
- OpExecutionMode %main LocalSize 8 8 1
- OpSource HLSL 660
- OpName %main "main"
- %uint = OpTypeInt 32 0
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %_ptr_Function_uint = OpTypePointer Function %uint
- %main = OpFunction %void None %5
- %7 = OpLabel
- %8 = OpVariable %_ptr_Function_uint Function
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_VULKAN_1_3);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, FunctionReturnPointer) {
- // Run DCE when a function returning a pointer to a reference is present
- const std::string text = R"(
- OpCapability Shader
- OpCapability PhysicalStorageBufferAddresses
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel PhysicalStorageBuffer64 GLSL450
- OpEntryPoint Vertex %2 "main" %3 %4
- OpSource GLSL 450
- OpSourceExtension "GL_EXT_buffer_reference"
- OpSourceExtension "GL_EXT_scalar_block_layout"
- OpName %4 "color"
- OpMemberDecorate %5 0 Offset 0
- OpDecorate %5 Block
- OpMemberDecorate %7 0 Offset 0
- OpDecorate %7 Block
- OpDecorate %8 AliasedPointer
- OpDecorate %4 Location 0
- %9 = OpTypeVoid
- %10 = OpTypeFunction %9
- OpTypeForwardPointer %11 PhysicalStorageBuffer
- %12 = OpTypeInt 32 0
- %5 = OpTypeStruct %12
- %11 = OpTypePointer PhysicalStorageBuffer %5
- ;CHECK: [[pt:%\w+]] = OpTypePointer PhysicalStorageBuffer {{%\w+}}
- %13 = OpTypeFunction %11
- ;CHECK: [[pt_fn:%\w+]] = OpTypeFunction [[pt]]
- %7 = OpTypeStruct %11
- %14 = OpTypePointer PushConstant %7
- %3 = OpVariable %14 PushConstant
- %15 = OpTypeInt 32 1
- %16 = OpConstant %15 0
- %17 = OpTypePointer PushConstant %11
- %18 = OpTypePointer Function %11
- %19 = OpTypeFloat 32
- %20 = OpTypeVector %19 4
- %21 = OpTypePointer Output %20
- %4 = OpVariable %21 Output
- %22 = OpConstant %19 1
- %23 = OpConstant %19 0
- %24 = OpConstantComposite %20 %22 %23 %22 %22
- %6 = OpFunction %11 None %13
- ;CHECK: [[fn:%\w+]] = OpFunction [[pt]] None [[pt_fn]]
- %27 = OpLabel
- %28 = OpAccessChain %17 %3 %16
- %29 = OpLoad %11 %28
- OpReturnValue %29
- OpFunctionEnd
- %2 = OpFunction %9 None %10
- %25 = OpLabel
- %8 = OpVariable %18 Function
- %26 = OpFunctionCall %11 %6
- ;CHECK: {{%\w+}} = OpFunctionCall [[pt]] [[fn]]
- OpStore %8 %26
- OpStore %4 %24
- OpReturn
- OpFunctionEnd
- )";
- // For physical storage buffer support
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, KeepBeginEndInvocationInterlock) {
- // OpBeginInvocationInterlockEXT and OpEndInvocationInterlockEXT delimit a
- // critical section. As such, they should be treated as if they have side
- // effects and should not be removed.
- const std::string test =
- R"(OpCapability Shader
- OpCapability FragmentShaderSampleInterlockEXT
- OpExtension "SPV_EXT_fragment_shader_interlock"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "main" %gl_FragCoord
- OpExecutionMode %1 OriginUpperLeft
- OpExecutionMode %1 SampleInterlockOrderedEXT
- OpDecorate %gl_FragCoord BuiltIn FragCoord
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %void = OpTypeVoid
- %8 = OpTypeFunction %void
- %bool = OpTypeBool
- %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
- %1 = OpFunction %void None %8
- %10 = OpLabel
- %11 = OpLoad %v4float %gl_FragCoord
- %12 = OpCompositeExtract %float %11 0
- %13 = OpFOrdGreaterThan %bool %12 %float_0
- OpSelectionMerge %14 None
- OpBranchConditional %13 %15 %16
- %15 = OpLabel
- OpBeginInvocationInterlockEXT
- OpBranch %14
- %16 = OpLabel
- OpBeginInvocationInterlockEXT
- OpBranch %14
- %14 = OpLabel
- OpEndInvocationInterlockEXT
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(test, test, true, true);
- }
- TEST_F(AggressiveDCETest, StoringAPointer) {
- // A store that stores a pointer should not be kept live because the value
- // being stored is eventually loaded from.
- const std::string text = R"(
- OpCapability CooperativeMatrixKHR
- OpCapability Shader
- OpExtension "SPV_KHR_cooperative_matrix"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %1 "main" %2
- OpExecutionMode %1 LocalSize 64 1 1
- OpSource HLSL 600
- OpDecorate %2 DescriptorSet 0
- OpDecorate %2 Binding 0
- OpDecorate %_runtimearr_int ArrayStride 4
- OpMemberDecorate %_struct_4 0 Offset 0
- OpDecorate %_struct_4 Block
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %int_1 = OpConstant %int 1
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %uint_64 = OpConstant %uint 64
- %uint_3 = OpConstant %uint 3
- %uint_16 = OpConstant %uint 16
- %uint_4 = OpConstant %uint 4
- %coop_stride = OpConstant %int 42
- %_runtimearr_int = OpTypeRuntimeArray %int
- %_struct_4 = OpTypeStruct %_runtimearr_int
- %_ptr_StorageBuffer__struct_4 = OpTypePointer StorageBuffer %_struct_4
- %void = OpTypeVoid
- %16 = OpTypeFunction %void
- ; CHECK: [[mat:%\w+]] = OpTypeCooperativeMatrixKHR %int %uint_3 %uint_16 %uint_4 %uint_0
- %17 = OpTypeCooperativeMatrixKHR %int %uint_3 %uint_16 %uint_4 %uint_0
- ; CHECK: [[struct:%\w+]] = OpTypeStruct [[mat]]
- %_struct_18 = OpTypeStruct %17
- ; CHECK: [[ptr:%\w+]] = OpTypePointer Function [[struct]]
- %_ptr_Function__struct_18 = OpTypePointer Function %_struct_18
- %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
- %_ptr_Function_17 = OpTypePointer Function %17
- %_ptr_Function_int = OpTypePointer Function %int
- %_ptr_Function__ptr_Function_int = OpTypePointer Function %_ptr_Function_int
- %2 = OpVariable %_ptr_StorageBuffer__struct_4 StorageBuffer
- ; The stored to the fist two variables should be removed and the variables
- ; as well. The only function scope variable should be the cooperative matrix.
- ; CHECK: OpFunction
- ; CHECK-NOT: OpVariable %_ptr_Function__ptr_Function_int Function
- ; CHECK: OpVariable [[ptr]] Function
- ; CHECK-NOT: OpVariable
- %1 = OpFunction %void None %16
- %24 = OpLabel
- %25 = OpVariable %_ptr_Function__ptr_Function_int Function
- %26 = OpVariable %_ptr_Function__ptr_Function_int Function
- %27 = OpVariable %_ptr_Function__struct_18 Function
- %28 = OpAccessChain %_ptr_StorageBuffer_int %2 %int_0 %uint_0
- %29 = OpCooperativeMatrixLoadKHR %17 %28 %int_1 %coop_stride
- %30 = OpCompositeConstruct %_struct_18 %29
- OpStore %27 %30
- %31 = OpAccessChain %_ptr_Function_17 %27 %int_0
- %32 = OpAccessChain %_ptr_Function_int %27 %int_0 %uint_0
- OpStore %26 %32
- %33 = OpLoad %int %32
- %34 = OpIAdd %int %33 %int_1
- OpStore %25 %32
- OpStore %32 %34
- %35 = OpAccessChain %_ptr_StorageBuffer_int %2 %int_0 %uint_64
- %36 = OpLoad %17 %31
- OpCooperativeMatrixStoreKHR %35 %36 %int_0 %coop_stride
- OpReturn
- OpFunctionEnd
- )";
- // For physical storage buffer support
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
- SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
- }
- TEST_F(AggressiveDCETest, FunctionDeclaration) {
- // Ensure the optimizer can handle traversing over a function declaration
- // 'myfunc' which has no blocks
- const std::string text = R"(OpCapability Linkage
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %PSMain "main" %entryPointParam_PSMain
- OpExecutionMode %PSMain OriginUpperLeft
- OpSource Slang 1
- OpName %myfunc "myfunc"
- OpName %entryPointParam_PSMain "entryPointParam_PSMain"
- OpName %PSMain "PSMain"
- OpDecorate %myfunc LinkageAttributes "_S6myfuncp0pv4f" Import
- OpDecorate %entryPointParam_PSMain Location 0
- %void = OpTypeVoid
- %5 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %8 = OpTypeFunction %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %entryPointParam_PSMain = OpVariable %_ptr_Output_v4float Output
- %myfunc = OpFunction %v4float None %8
- OpFunctionEnd
- %PSMain = OpFunction %void None %5
- %10 = OpLabel
- %11 = OpFunctionCall %v4float %myfunc
- OpStore %entryPointParam_PSMain %11
- OpReturn
- OpFunctionEnd
- )";
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<AggressiveDCEPass>(text, text, true, true);
- }
- TEST_F(AggressiveDCETest, MarkCentroidInterpolantLive) {
- const std::string spirv =
- R"(OpCapability InterpolationFunction
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_Target
- OpExecutionMode %main OriginUpperLeft
- OpSource HLSL 680
- OpName %in_var_COLOR "in.var.COLOR"
- OpName %out_var_SV_Target "out.var.SV_Target"
- OpName %main "main"
- OpName %param_var_p1 "param.var.p1"
- OpDecorate %in_var_COLOR Location 0
- OpDecorate %out_var_SV_Target Location 0
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %11 = OpTypeFunction %void
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
- %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %11
- %13 = OpLabel
- %14 = OpVariable %_ptr_Function_v4float Function
- %param_var_p1 = OpVariable %_ptr_Function_v4float Function
- %15 = OpLoad %v4float %in_var_COLOR
- OpStore %param_var_p1 %15
- %16 = OpExtInst %v4float %1 InterpolateAtCentroid %param_var_p1
- OpStore %14 %16
- %17 = OpLoad %v4float %14
- OpStore %out_var_SV_Target %17
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(spirv, spirv, true, false);
- }
- TEST_F(AggressiveDCETest, MarkSampleInterpolantLive) {
- const std::string spirv =
- R"(OpCapability InterpolationFunction
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_Target
- OpExecutionMode %main OriginUpperLeft
- OpSource HLSL 680
- OpName %in_var_COLOR "in.var.COLOR"
- OpName %out_var_SV_Target "out.var.SV_Target"
- OpName %main "main"
- OpName %param_var_p1 "param.var.p1"
- OpDecorate %in_var_COLOR Location 0
- OpDecorate %out_var_SV_Target Location 0
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 1
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %12 = OpTypeFunction %void
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
- %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
- %int_123 = OpConstant %int 123
- %main = OpFunction %void None %12
- %15 = OpLabel
- %16 = OpVariable %_ptr_Function_v4float Function
- %param_var_p1 = OpVariable %_ptr_Function_v4float Function
- %17 = OpLoad %v4float %in_var_COLOR
- OpStore %param_var_p1 %17
- %18 = OpExtInst %v4float %1 InterpolateAtSample %param_var_p1 %int_123
- OpStore %16 %18
- %19 = OpLoad %v4float %16
- OpStore %out_var_SV_Target %19
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(spirv, spirv, true, false);
- }
- TEST_F(AggressiveDCETest, MarkOffsetInterpolantLive) {
- const std::string spirv =
- R"(OpCapability InterpolationFunction
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_Target
- OpExecutionMode %main OriginUpperLeft
- OpSource HLSL 680
- OpName %in_var_COLOR "in.var.COLOR"
- OpName %out_var_SV_Target "out.var.SV_Target"
- OpName %main "main"
- OpName %param_var_p1 "param.var.p1"
- OpDecorate %in_var_COLOR Location 0
- OpDecorate %out_var_SV_Target Location 0
- %float = OpTypeFloat 32
- %int = OpTypeInt 32 1
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %12 = OpTypeFunction %void
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
- %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
- %int_123 = OpConstant %int 123
- %main = OpFunction %void None %12
- %15 = OpLabel
- %16 = OpVariable %_ptr_Function_v4float Function
- %param_var_p1 = OpVariable %_ptr_Function_v4float Function
- %17 = OpLoad %v4float %in_var_COLOR
- OpStore %param_var_p1 %17
- %18 = OpExtInst %v4float %1 InterpolateAtOffset %param_var_p1 %int_123
- OpStore %16 %18
- %19 = OpLoad %v4float %16
- OpStore %out_var_SV_Target %19
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndCheck<AggressiveDCEPass>(spirv, spirv, true, false);
- }
- TEST_F(AggressiveDCETest, NoEliminateOpSource) {
- // Should not eliminate OpSource
- const std::string text =
- R"(OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET
- OpExecutionMode %main OriginUpperLeft
- %4 = OpString "D:\\directxshadercompiler\\tools\\clang\\test\\CodeGenSPIRV\\spirv.debug.opsource.include.hlsl"
- %5 = OpString "D:\\directxshadercompiler\\tools\\clang\\test\\CodeGenSPIRV/spirv.debug.opsource.include-file.hlsli"
- OpSource HLSL 600 %4 "// RUN: %dxc -T ps_6_0 -E main -Zi %s -spirv | FileCheck %s
- #include \"spirv.debug.opsource.include-file.hlsli\"
- struct ColorType
- {
- float4 position : SV_POSITION;
- float4 color : COLOR;
- };
- float4 main(UBER_TYPE(Color) input) : SV_TARGET
- {
- return input.color;
- }
- "
- OpSource HLSL 600 %5 "#define UBER_TYPE(x) x ## Type
- "
- OpName %in_var_COLOR "in.var.COLOR"
- OpName %out_var_SV_TARGET "out.var.SV_TARGET"
- OpName %main "main"
- OpDecorate %in_var_COLOR Location 0
- OpDecorate %out_var_SV_TARGET Location 0
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %11 = OpTypeFunction %void
- %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
- %out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
- OpLine %4 22 1
- %main = OpFunction %void None %11
- OpNoLine
- %12 = OpLabel
- OpLine %4 22 1
- %13 = OpLoad %v4float %in_var_COLOR
- OpStore %out_var_SV_TARGET %13
- OpLine %4 25 1
- OpReturn
- OpFunctionEnd
- )";
- auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
- text, /* skip_nop = */ true, /* skip_validation = */ false);
- EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
- const std::string& output = std::get<0>(result);
- EXPECT_THAT(
- output,
- HasSubstr("OpSource HLSL 600 %5 \"#define UBER_TYPE(x) x ## Type"));
- }
- TEST_F(AggressiveDCETest, EliminateCopyLogical) {
- const std::string before = R"(
- ; CHECK: [[float32:%\w+]] = OpTypeFloat 32
- ; CHECK: [[v4float:%\w+]] = OpTypeVector [[float32]] 4
- ; CHECK-NOT: %10 = OpTypeArray [[v4float]] %9
- ; CHECK-NOT: %11 = OpTypeStruct %10 %10
- ; CHECK-NOT: %22 = OpTypePointer Uniform %16
- ; CHECK-NOT: %38 = OpTypePointer Function [[v4float]]
- ; CHECK-NOT: %43 = OpTypePointer Function %10
- ; CHECK-NOT: %44 = OpVariable %42 Function
- ; CHECK-NOT: %23 = OpAccessChain %22 %19 %21
- ; CHECK-NOT: %24 = OpLoad %16 %23
- ; CHECK-NOT: %25 = OpCopyLogical %11 %24
- ; CHECK-NOT: %46 = OpCompositeExtract %10 %25 0
- ; CHECK-NOT: OpStore %44 %46
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %4 "main" %19 %30 %32
- OpSource GLSL 430
- OpName %4 "main"
- OpDecorate %14 ArrayStride 16
- OpDecorate %15 ArrayStride 16
- OpMemberDecorate %16 0 Offset 0
- OpMemberDecorate %16 1 Offset 32
- OpDecorate %17 Block
- OpMemberDecorate %17 0 Offset 0
- OpDecorate %19 Binding 0
- OpDecorate %19 DescriptorSet 0
- OpDecorate %28 Block
- OpMemberDecorate %28 0 BuiltIn Position
- OpMemberDecorate %28 1 BuiltIn PointSize
- OpMemberDecorate %28 2 BuiltIn ClipDistance
- OpDecorate %32 Location 0
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeFloat 32
- %7 = OpTypeVector %6 4
- %8 = OpTypeInt 32 0
- %9 = OpConstant %8 2
- %10 = OpTypeArray %7 %9
- %11 = OpTypeStruct %10 %10
- %14 = OpTypeArray %7 %9
- %15 = OpTypeArray %7 %9
- %16 = OpTypeStruct %14 %15
- %17 = OpTypeStruct %16
- %18 = OpTypePointer Uniform %17
- %19 = OpVariable %18 Uniform
- %20 = OpTypeInt 32 1
- %21 = OpConstant %20 0
- %22 = OpTypePointer Uniform %16
- %26 = OpConstant %8 1
- %27 = OpTypeArray %6 %26
- %28 = OpTypeStruct %7 %6 %27
- %29 = OpTypePointer Output %28
- %30 = OpVariable %29 Output
- %31 = OpTypePointer Input %7
- %32 = OpVariable %31 Input
- %33 = OpConstant %8 0
- %34 = OpTypePointer Input %6
- %38 = OpTypePointer Function %7
- %41 = OpTypePointer Output %7
- %43 = OpTypePointer Function %10
- %48 = OpTypePointer Uniform %14
- %49 = OpTypePointer Uniform %7
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %44 = OpVariable %43 Function
- %23 = OpAccessChain %22 %19 %21
- %24 = OpLoad %16 %23
- %25 = OpCopyLogical %11 %24
- %46 = OpCompositeExtract %10 %25 0
- %50 = OpAccessChain %48 %19 %21 %33
- OpStore %44 %46
- %35 = OpAccessChain %34 %32 %33
- %36 = OpLoad %6 %35
- %37 = OpConvertFToS %20 %36
- %47 = OpAccessChain %49 %50 %37
- %40 = OpLoad %7 %47
- %42 = OpAccessChain %41 %30 %21
- OpStore %42 %40
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_UNIVERSAL_1_6);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
- SinglePassRunAndMatch<AggressiveDCEPass>(before, true);
- }
- TEST_F(AggressiveDCETest, KeepCopyLogical) {
- const std::string before = R"(
- ; CHECK: OpCopyLogical
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint GLCompute %4 "main" %15 %23 %38
- OpExecutionMode %4 LocalSize 32 32 1
- OpSource GLSL 430
- OpName %4 "main"
- OpDecorate %10 ArrayStride 16
- OpDecorate %11 ArrayStride 16
- OpMemberDecorate %12 0 Offset 0
- OpMemberDecorate %12 1 Offset 2048
- OpDecorate %13 Block
- OpMemberDecorate %13 0 NonReadable
- OpMemberDecorate %13 0 Offset 0
- OpDecorate %15 NonReadable
- OpDecorate %15 Binding 1
- OpDecorate %15 DescriptorSet 0
- OpDecorate %18 ArrayStride 16
- OpDecorate %19 ArrayStride 16
- OpMemberDecorate %20 0 Offset 0
- OpMemberDecorate %20 1 Offset 2048
- OpDecorate %21 Block
- OpMemberDecorate %21 0 NonWritable
- OpMemberDecorate %21 0 Offset 0
- OpDecorate %23 NonWritable
- OpDecorate %23 Binding 0
- OpDecorate %23 DescriptorSet 0
- OpDecorate %30 ArrayStride 16
- OpDecorate %31 ArrayStride 16
- OpMemberDecorate %32 0 Offset 0
- OpMemberDecorate %32 1 Offset 2048
- OpDecorate %34 ArrayStride 4096
- OpMemberDecorate %35 0 Offset 0
- OpDecorate %36 Block
- OpMemberDecorate %36 0 Offset 0
- OpDecorate %38 Binding 0
- OpDecorate %38 DescriptorSet 0
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeFloat 32
- %7 = OpTypeVector %6 4
- %8 = OpTypeInt 32 0
- %9 = OpConstant %8 128
- %10 = OpTypeArray %7 %9
- %11 = OpTypeArray %7 %9
- %12 = OpTypeStruct %10 %11
- %13 = OpTypeStruct %12
- %14 = OpTypePointer StorageBuffer %13
- %15 = OpVariable %14 StorageBuffer
- %16 = OpTypeInt 32 1
- %17 = OpConstant %16 0
- %18 = OpTypeArray %7 %9
- %19 = OpTypeArray %7 %9
- %20 = OpTypeStruct %18 %19
- %21 = OpTypeStruct %20
- %22 = OpTypePointer StorageBuffer %21
- %23 = OpVariable %22 StorageBuffer
- %24 = OpTypePointer StorageBuffer %20
- %27 = OpTypePointer StorageBuffer %12
- %30 = OpTypeArray %7 %9
- %31 = OpTypeArray %7 %9
- %32 = OpTypeStruct %30 %31
- %33 = OpConstant %8 8
- %34 = OpTypeArray %32 %33
- %35 = OpTypeStruct %34
- %36 = OpTypeStruct %35
- %37 = OpTypePointer Uniform %36
- %38 = OpVariable %37 Uniform
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %25 = OpAccessChain %24 %23 %17
- %26 = OpLoad %20 %25
- %28 = OpAccessChain %27 %15 %17
- %29 = OpCopyLogical %12 %26
- OpStore %28 %29
- OpReturn
- OpFunctionEnd
- )";
- SetTargetEnv(SPV_ENV_UNIVERSAL_1_6);
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
- SinglePassRunAndMatch<AggressiveDCEPass>(before, true);
- }
- } // namespace
- } // namespace opt
- } // namespace spvtools
|