aggressive_dead_code_elim_test.cpp 276 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481
  1. // Copyright (c) 2017 Valve Corporation
  2. // Copyright (c) 2017 LunarG Inc.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. #include <string>
  16. #include <vector>
  17. #include "gmock/gmock.h"
  18. #include "test/opt/assembly_builder.h"
  19. #include "test/opt/pass_fixture.h"
  20. #include "test/opt/pass_utils.h"
  21. namespace spvtools {
  22. namespace opt {
  23. namespace {
  24. using AggressiveDCETest = PassTest<::testing::Test>;
  25. using ::testing::HasSubstr;
  26. TEST_F(AggressiveDCETest, EliminateExtendedInst) {
  27. // #version 140
  28. //
  29. // in vec4 BaseColor;
  30. // in vec4 Dead;
  31. //
  32. // void main()
  33. // {
  34. // vec4 v = BaseColor;
  35. // vec4 dv = sqrt(Dead);
  36. // gl_FragColor = v;
  37. // }
  38. const std::string spirv = R"(
  39. OpCapability Shader
  40. %1 = OpExtInstImport "GLSL.std.450"
  41. OpMemoryModel Logical GLSL450
  42. ; CHECK: OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  43. OpEntryPoint Fragment %main "main" %BaseColor %Dead %gl_FragColor
  44. OpExecutionMode %main OriginUpperLeft
  45. OpSource GLSL 140
  46. OpName %main "main"
  47. OpName %v "v"
  48. OpName %BaseColor "BaseColor"
  49. ; CHECK-NOT: OpName %dv "dv"
  50. OpName %dv "dv"
  51. ; CHECK-NOT: OpName %Dead "Dead"
  52. OpName %Dead "Dead"
  53. OpName %gl_FragColor "gl_FragColor"
  54. %void = OpTypeVoid
  55. %9 = OpTypeFunction %void
  56. %float = OpTypeFloat 32
  57. %v4float = OpTypeVector %float 4
  58. %_ptr_Function_v4float = OpTypePointer Function %v4float
  59. %_ptr_Input_v4float = OpTypePointer Input %v4float
  60. %BaseColor = OpVariable %_ptr_Input_v4float Input
  61. ; CHECK-NOT: %Dead = OpVariable
  62. %Dead = OpVariable %_ptr_Input_v4float Input
  63. %_ptr_Output_v4float = OpTypePointer Output %v4float
  64. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  65. %main = OpFunction %void None %9
  66. %15 = OpLabel
  67. %v = OpVariable %_ptr_Function_v4float Function
  68. ; CHECK-NOT: %dv = OpVariable
  69. %dv = OpVariable %_ptr_Function_v4float Function
  70. %16 = OpLoad %v4float %BaseColor
  71. OpStore %v %16
  72. ; CHECK-NOT: OpLoad %v4float %Dead
  73. %17 = OpLoad %v4float %Dead
  74. ; CHECK-NOT: OpExtInst %v4float %1 Sqrt
  75. %18 = OpExtInst %v4float %1 Sqrt %17
  76. ; CHECK-NOT: OpStore %dv
  77. OpStore %dv %18
  78. %19 = OpLoad %v4float %v
  79. OpStore %gl_FragColor %19
  80. OpReturn
  81. OpFunctionEnd
  82. )";
  83. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  84. }
  85. TEST_F(AggressiveDCETest, NoEliminateFrexp) {
  86. // Note: SPIR-V hand-edited to utilize Frexp
  87. //
  88. // #version 450
  89. //
  90. // in vec4 BaseColor;
  91. // in vec4 Dead;
  92. // out vec4 Color;
  93. // out ivec4 iv2;
  94. //
  95. // void main()
  96. // {
  97. // vec4 v = BaseColor;
  98. // vec4 dv = frexp(Dead, iv2);
  99. // Color = v;
  100. // }
  101. const std::string predefs1 =
  102. R"(OpCapability Shader
  103. %1 = OpExtInstImport "GLSL.std.450"
  104. OpMemoryModel Logical GLSL450
  105. OpEntryPoint Fragment %main "main" %BaseColor %Dead %iv2 %Color
  106. OpExecutionMode %main OriginUpperLeft
  107. OpSource GLSL 450
  108. )";
  109. const std::string names_before =
  110. R"(OpName %main "main"
  111. OpName %v "v"
  112. OpName %BaseColor "BaseColor"
  113. OpName %dv "dv"
  114. OpName %Dead "Dead"
  115. OpName %iv2 "iv2"
  116. OpName %ResType "ResType"
  117. OpName %Color "Color"
  118. )";
  119. const std::string names_after =
  120. R"(OpName %main "main"
  121. OpName %v "v"
  122. OpName %BaseColor "BaseColor"
  123. OpName %Dead "Dead"
  124. OpName %iv2 "iv2"
  125. OpName %Color "Color"
  126. )";
  127. const std::string predefs2_before =
  128. R"(%void = OpTypeVoid
  129. %11 = OpTypeFunction %void
  130. %float = OpTypeFloat 32
  131. %v4float = OpTypeVector %float 4
  132. %_ptr_Function_v4float = OpTypePointer Function %v4float
  133. %_ptr_Input_v4float = OpTypePointer Input %v4float
  134. %BaseColor = OpVariable %_ptr_Input_v4float Input
  135. %Dead = OpVariable %_ptr_Input_v4float Input
  136. %int = OpTypeInt 32 1
  137. %v4int = OpTypeVector %int 4
  138. %_ptr_Output_v4int = OpTypePointer Output %v4int
  139. %iv2 = OpVariable %_ptr_Output_v4int Output
  140. %ResType = OpTypeStruct %v4float %v4int
  141. %_ptr_Output_v4float = OpTypePointer Output %v4float
  142. %Color = OpVariable %_ptr_Output_v4float Output
  143. )";
  144. const std::string predefs2_after =
  145. R"(%void = OpTypeVoid
  146. %11 = OpTypeFunction %void
  147. %float = OpTypeFloat 32
  148. %v4float = OpTypeVector %float 4
  149. %_ptr_Function_v4float = OpTypePointer Function %v4float
  150. %_ptr_Input_v4float = OpTypePointer Input %v4float
  151. %BaseColor = OpVariable %_ptr_Input_v4float Input
  152. %Dead = OpVariable %_ptr_Input_v4float Input
  153. %int = OpTypeInt 32 1
  154. %v4int = OpTypeVector %int 4
  155. %_ptr_Output_v4int = OpTypePointer Output %v4int
  156. %iv2 = OpVariable %_ptr_Output_v4int Output
  157. %_ptr_Output_v4float = OpTypePointer Output %v4float
  158. %Color = OpVariable %_ptr_Output_v4float Output
  159. )";
  160. const std::string func_before =
  161. R"(%main = OpFunction %void None %11
  162. %20 = OpLabel
  163. %v = OpVariable %_ptr_Function_v4float Function
  164. %dv = OpVariable %_ptr_Function_v4float Function
  165. %21 = OpLoad %v4float %BaseColor
  166. OpStore %v %21
  167. %22 = OpLoad %v4float %Dead
  168. %23 = OpExtInst %v4float %1 Frexp %22 %iv2
  169. OpStore %dv %23
  170. %24 = OpLoad %v4float %v
  171. OpStore %Color %24
  172. OpReturn
  173. OpFunctionEnd
  174. )";
  175. const std::string func_after =
  176. R"(%main = OpFunction %void None %11
  177. %20 = OpLabel
  178. %v = OpVariable %_ptr_Function_v4float Function
  179. %21 = OpLoad %v4float %BaseColor
  180. OpStore %v %21
  181. %22 = OpLoad %v4float %Dead
  182. %23 = OpExtInst %v4float %1 Frexp %22 %iv2
  183. %24 = OpLoad %v4float %v
  184. OpStore %Color %24
  185. OpReturn
  186. OpFunctionEnd
  187. )";
  188. SinglePassRunAndCheck<AggressiveDCEPass>(
  189. predefs1 + names_before + predefs2_before + func_before,
  190. predefs1 + names_after + predefs2_after + func_after, true, true);
  191. }
  192. TEST_F(AggressiveDCETest, EliminateDecorate) {
  193. // Note: The SPIR-V was hand-edited to add the OpDecorate
  194. //
  195. // #version 140
  196. //
  197. // in vec4 BaseColor;
  198. // in vec4 Dead;
  199. //
  200. // void main()
  201. // {
  202. // vec4 v = BaseColor;
  203. // vec4 dv = Dead * 0.5;
  204. // gl_FragColor = v;
  205. // }
  206. const std::string spirv =
  207. R"(
  208. OpCapability Shader
  209. %1 = OpExtInstImport "GLSL.std.450"
  210. OpMemoryModel Logical GLSL450
  211. OpEntryPoint Fragment %main "main" %BaseColor %Dead %gl_FragColor
  212. OpExecutionMode %main OriginUpperLeft
  213. OpSource GLSL 140
  214. OpName %main "main"
  215. OpName %v "v"
  216. OpName %BaseColor "BaseColor"
  217. OpName %dv "dv"
  218. OpName %Dead "Dead"
  219. OpName %gl_FragColor "gl_FragColor"
  220. ; CHECK-NOT: OpDecorate
  221. OpDecorate %8 RelaxedPrecision
  222. %void = OpTypeVoid
  223. %10 = OpTypeFunction %void
  224. %float = OpTypeFloat 32
  225. %v4float = OpTypeVector %float 4
  226. %_ptr_Function_v4float = OpTypePointer Function %v4float
  227. %_ptr_Input_v4float = OpTypePointer Input %v4float
  228. %BaseColor = OpVariable %_ptr_Input_v4float Input
  229. %Dead = OpVariable %_ptr_Input_v4float Input
  230. %float_0_5 = OpConstant %float 0.5
  231. %_ptr_Output_v4float = OpTypePointer Output %v4float
  232. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  233. %main = OpFunction %void None %10
  234. %17 = OpLabel
  235. %v = OpVariable %_ptr_Function_v4float Function
  236. %dv = OpVariable %_ptr_Function_v4float Function
  237. %18 = OpLoad %v4float %BaseColor
  238. OpStore %v %18
  239. %19 = OpLoad %v4float %Dead
  240. ; CHECK-NOT: OpVectorTimesScalar
  241. %8 = OpVectorTimesScalar %v4float %19 %float_0_5
  242. OpStore %dv %8
  243. %20 = OpLoad %v4float %v
  244. OpStore %gl_FragColor %20
  245. OpReturn
  246. OpFunctionEnd
  247. )";
  248. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  249. }
  250. TEST_F(AggressiveDCETest, Simple) {
  251. // #version 140
  252. //
  253. // in vec4 BaseColor;
  254. // in vec4 Dead;
  255. //
  256. // void main()
  257. // {
  258. // vec4 v = BaseColor;
  259. // vec4 dv = Dead;
  260. // gl_FragColor = v;
  261. // }
  262. const std::string spirv =
  263. R"(
  264. OpCapability Shader
  265. %1 = OpExtInstImport "GLSL.std.450"
  266. OpMemoryModel Logical GLSL450
  267. ; CHECK: OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  268. OpEntryPoint Fragment %main "main" %BaseColor %Dead %gl_FragColor
  269. OpExecutionMode %main OriginUpperLeft
  270. OpSource GLSL 140
  271. OpName %main "main"
  272. OpName %v "v"
  273. OpName %BaseColor "BaseColor"
  274. ; CHECK-NOT: OpName %dv "dv"
  275. OpName %dv "dv"
  276. ; CHECK-NOT: OpName %Dead "Dead"
  277. OpName %Dead "Dead"
  278. OpName %gl_FragColor "gl_FragColor"
  279. %void = OpTypeVoid
  280. %9 = OpTypeFunction %void
  281. %float = OpTypeFloat 32
  282. %v4float = OpTypeVector %float 4
  283. %_ptr_Function_v4float = OpTypePointer Function %v4float
  284. %_ptr_Input_v4float = OpTypePointer Input %v4float
  285. %BaseColor = OpVariable %_ptr_Input_v4float Input
  286. ; CHECK-NOT: %Dead = OpVariable
  287. %Dead = OpVariable %_ptr_Input_v4float Input
  288. %_ptr_Output_v4float = OpTypePointer Output %v4float
  289. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  290. %main = OpFunction %void None %9
  291. %15 = OpLabel
  292. %v = OpVariable %_ptr_Function_v4float Function
  293. ; CHECK-NOT: %dv = OpVariable
  294. %dv = OpVariable %_ptr_Function_v4float Function
  295. %16 = OpLoad %v4float %BaseColor
  296. OpStore %v %16
  297. ; CHECK-NOT: OpLoad %v4float %Dead
  298. %17 = OpLoad %v4float %Dead
  299. ; CHECK-NOT: OpStore %dv
  300. OpStore %dv %17
  301. %18 = OpLoad %v4float %v
  302. OpStore %gl_FragColor %18
  303. OpReturn
  304. OpFunctionEnd
  305. )";
  306. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  307. }
  308. TEST_F(AggressiveDCETest, OptAllowListExtension) {
  309. // #version 140
  310. //
  311. // in vec4 BaseColor;
  312. // in vec4 Dead;
  313. //
  314. // void main()
  315. // {
  316. // vec4 v = BaseColor;
  317. // vec4 dv = Dead;
  318. // gl_FragColor = v;
  319. // }
  320. const std::string spirv =
  321. R"(OpCapability Shader
  322. OpExtension "SPV_AMD_gpu_shader_int16"
  323. %1 = OpExtInstImport "GLSL.std.450"
  324. OpMemoryModel Logical GLSL450
  325. ; CHECK: OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  326. OpEntryPoint Fragment %main "main" %BaseColor %Dead %gl_FragColor
  327. OpExecutionMode %main OriginUpperLeft
  328. OpSource GLSL 140
  329. OpName %main "main"
  330. OpName %v "v"
  331. OpName %BaseColor "BaseColor"
  332. OpName %dv "dv"
  333. OpName %Dead "Dead"
  334. OpName %gl_FragColor "gl_FragColor"
  335. %void = OpTypeVoid
  336. %9 = OpTypeFunction %void
  337. %float = OpTypeFloat 32
  338. %v4float = OpTypeVector %float 4
  339. %_ptr_Function_v4float = OpTypePointer Function %v4float
  340. %_ptr_Input_v4float = OpTypePointer Input %v4float
  341. %BaseColor = OpVariable %_ptr_Input_v4float Input
  342. %Dead = OpVariable %_ptr_Input_v4float Input
  343. %_ptr_Output_v4float = OpTypePointer Output %v4float
  344. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  345. %main = OpFunction %void None %9
  346. %15 = OpLabel
  347. %v = OpVariable %_ptr_Function_v4float Function
  348. %dv = OpVariable %_ptr_Function_v4float Function
  349. %16 = OpLoad %v4float %BaseColor
  350. OpStore %v %16
  351. %17 = OpLoad %v4float %Dead
  352. OpStore %dv %17
  353. %18 = OpLoad %v4float %v
  354. OpStore %gl_FragColor %18
  355. OpReturn
  356. OpFunctionEnd
  357. )";
  358. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  359. }
  360. TEST_F(AggressiveDCETest, NoOptDenyListExtension) {
  361. // #version 140
  362. //
  363. // in vec4 BaseColor;
  364. // in vec4 Dead;
  365. //
  366. // void main()
  367. // {
  368. // vec4 v = BaseColor;
  369. // vec4 dv = Dead;
  370. // gl_FragColor = v;
  371. // }
  372. const std::string assembly =
  373. R"(OpCapability Shader
  374. OpExtension "SPV_KHR_variable_pointers"
  375. %1 = OpExtInstImport "GLSL.std.450"
  376. OpMemoryModel Logical GLSL450
  377. OpEntryPoint Fragment %main "main" %BaseColor %Dead %gl_FragColor
  378. OpExecutionMode %main OriginUpperLeft
  379. OpSource GLSL 140
  380. OpName %main "main"
  381. OpName %v "v"
  382. OpName %BaseColor "BaseColor"
  383. OpName %dv "dv"
  384. OpName %Dead "Dead"
  385. OpName %gl_FragColor "gl_FragColor"
  386. %void = OpTypeVoid
  387. %9 = OpTypeFunction %void
  388. %float = OpTypeFloat 32
  389. %v4float = OpTypeVector %float 4
  390. %_ptr_Function_v4float = OpTypePointer Function %v4float
  391. %_ptr_Input_v4float = OpTypePointer Input %v4float
  392. %BaseColor = OpVariable %_ptr_Input_v4float Input
  393. %Dead = OpVariable %_ptr_Input_v4float Input
  394. %_ptr_Output_v4float = OpTypePointer Output %v4float
  395. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  396. %main = OpFunction %void None %9
  397. %15 = OpLabel
  398. %v = OpVariable %_ptr_Function_v4float Function
  399. %dv = OpVariable %_ptr_Function_v4float Function
  400. %16 = OpLoad %v4float %BaseColor
  401. OpStore %v %16
  402. %17 = OpLoad %v4float %Dead
  403. OpStore %dv %17
  404. %18 = OpLoad %v4float %v
  405. OpStore %gl_FragColor %18
  406. OpReturn
  407. OpFunctionEnd
  408. )";
  409. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  410. }
  411. TEST_F(AggressiveDCETest, ElimWithCall) {
  412. // This demonstrates that "dead" function calls are not eliminated.
  413. // Also demonstrates that DCE will happen in presence of function call.
  414. // #version 140
  415. // in vec4 i1;
  416. // in vec4 i2;
  417. //
  418. // void nothing(vec4 v)
  419. // {
  420. // }
  421. //
  422. // void main()
  423. // {
  424. // vec4 v1 = i1;
  425. // vec4 v2 = i2;
  426. // nothing(v1);
  427. // gl_FragColor = vec4(0.0);
  428. // }
  429. const std::string text =
  430. R"( OpCapability Shader
  431. %1 = OpExtInstImport "GLSL.std.450"
  432. OpMemoryModel Logical GLSL450
  433. OpEntryPoint Fragment %main "main" %i1 %i2 %gl_FragColor
  434. OpExecutionMode %main OriginUpperLeft
  435. OpSource GLSL 140
  436. OpName %main "main"
  437. OpName %nothing_vf4_ "nothing(vf4;"
  438. OpName %v "v"
  439. OpName %v1 "v1"
  440. OpName %i1 "i1"
  441. OpName %v2 "v2"
  442. OpName %i2 "i2"
  443. OpName %param "param"
  444. OpName %gl_FragColor "gl_FragColor"
  445. %void = OpTypeVoid
  446. %12 = OpTypeFunction %void
  447. %float = OpTypeFloat 32
  448. %v4float = OpTypeVector %float 4
  449. %_ptr_Function_v4float = OpTypePointer Function %v4float
  450. %16 = OpTypeFunction %void %_ptr_Function_v4float
  451. %_ptr_Input_v4float = OpTypePointer Input %v4float
  452. %i1 = OpVariable %_ptr_Input_v4float Input
  453. %i2 = OpVariable %_ptr_Input_v4float Input
  454. %_ptr_Output_v4float = OpTypePointer Output %v4float
  455. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  456. %float_0 = OpConstant %float 0
  457. %20 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  458. %main = OpFunction %void None %12
  459. %21 = OpLabel
  460. %v1 = OpVariable %_ptr_Function_v4float Function
  461. %v2 = OpVariable %_ptr_Function_v4float Function
  462. %param = OpVariable %_ptr_Function_v4float Function
  463. %22 = OpLoad %v4float %i1
  464. OpStore %v1 %22
  465. ; CHECK-NOT: OpLoad %v4float %i2
  466. %23 = OpLoad %v4float %i2
  467. ; CHECK-NOT: OpStore %v2
  468. OpStore %v2 %23
  469. %24 = OpLoad %v4float %v1
  470. OpStore %param %24
  471. ; CHECK: OpFunctionCall %void %nothing_vf4_
  472. %25 = OpFunctionCall %void %nothing_vf4_ %param
  473. OpStore %gl_FragColor %20
  474. OpReturn
  475. OpFunctionEnd
  476. ; CHECK: %nothing_vf4_ = OpFunction
  477. %nothing_vf4_ = OpFunction %void None %16
  478. %v = OpFunctionParameter %_ptr_Function_v4float
  479. %26 = OpLabel
  480. OpReturn
  481. OpFunctionEnd
  482. )";
  483. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  484. }
  485. TEST_F(AggressiveDCETest, NoParamElim) {
  486. // This demonstrates that unused parameters are not eliminated, but
  487. // dead uses of them are.
  488. // #version 140
  489. //
  490. // in vec4 BaseColor;
  491. //
  492. // vec4 foo(vec4 v1, vec4 v2)
  493. // {
  494. // vec4 t = -v1;
  495. // return v2;
  496. // }
  497. //
  498. // void main()
  499. // {
  500. // vec4 dead;
  501. // gl_FragColor = foo(dead, BaseColor);
  502. // }
  503. const std::string defs_before =
  504. R"(OpCapability Shader
  505. %1 = OpExtInstImport "GLSL.std.450"
  506. OpMemoryModel Logical GLSL450
  507. OpEntryPoint Fragment %main "main" %gl_FragColor %BaseColor
  508. OpExecutionMode %main OriginUpperLeft
  509. OpSource GLSL 140
  510. OpName %main "main"
  511. OpName %foo_vf4_vf4_ "foo(vf4;vf4;"
  512. OpName %v1 "v1"
  513. OpName %v2 "v2"
  514. OpName %t "t"
  515. OpName %gl_FragColor "gl_FragColor"
  516. OpName %dead "dead"
  517. OpName %BaseColor "BaseColor"
  518. OpName %param "param"
  519. OpName %param_0 "param"
  520. %void = OpTypeVoid
  521. %13 = OpTypeFunction %void
  522. %float = OpTypeFloat 32
  523. %v4float = OpTypeVector %float 4
  524. %_ptr_Function_v4float = OpTypePointer Function %v4float
  525. %17 = OpTypeFunction %v4float %_ptr_Function_v4float %_ptr_Function_v4float
  526. %_ptr_Output_v4float = OpTypePointer Output %v4float
  527. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  528. %_ptr_Input_v4float = OpTypePointer Input %v4float
  529. %BaseColor = OpVariable %_ptr_Input_v4float Input
  530. %main = OpFunction %void None %13
  531. %20 = OpLabel
  532. %dead = OpVariable %_ptr_Function_v4float Function
  533. %param = OpVariable %_ptr_Function_v4float Function
  534. %param_0 = OpVariable %_ptr_Function_v4float Function
  535. %21 = OpLoad %v4float %dead
  536. OpStore %param %21
  537. %22 = OpLoad %v4float %BaseColor
  538. OpStore %param_0 %22
  539. %23 = OpFunctionCall %v4float %foo_vf4_vf4_ %param %param_0
  540. OpStore %gl_FragColor %23
  541. OpReturn
  542. OpFunctionEnd
  543. )";
  544. const std::string defs_after =
  545. R"(OpCapability Shader
  546. %1 = OpExtInstImport "GLSL.std.450"
  547. OpMemoryModel Logical GLSL450
  548. OpEntryPoint Fragment %main "main" %gl_FragColor %BaseColor
  549. OpExecutionMode %main OriginUpperLeft
  550. OpSource GLSL 140
  551. OpName %main "main"
  552. OpName %foo_vf4_vf4_ "foo(vf4;vf4;"
  553. OpName %v1 "v1"
  554. OpName %v2 "v2"
  555. OpName %gl_FragColor "gl_FragColor"
  556. OpName %dead "dead"
  557. OpName %BaseColor "BaseColor"
  558. OpName %param "param"
  559. OpName %param_0 "param"
  560. %void = OpTypeVoid
  561. %13 = OpTypeFunction %void
  562. %float = OpTypeFloat 32
  563. %v4float = OpTypeVector %float 4
  564. %_ptr_Function_v4float = OpTypePointer Function %v4float
  565. %17 = OpTypeFunction %v4float %_ptr_Function_v4float %_ptr_Function_v4float
  566. %_ptr_Output_v4float = OpTypePointer Output %v4float
  567. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  568. %_ptr_Input_v4float = OpTypePointer Input %v4float
  569. %BaseColor = OpVariable %_ptr_Input_v4float Input
  570. %main = OpFunction %void None %13
  571. %20 = OpLabel
  572. %dead = OpVariable %_ptr_Function_v4float Function
  573. %param = OpVariable %_ptr_Function_v4float Function
  574. %param_0 = OpVariable %_ptr_Function_v4float Function
  575. %21 = OpLoad %v4float %dead
  576. OpStore %param %21
  577. %22 = OpLoad %v4float %BaseColor
  578. OpStore %param_0 %22
  579. %23 = OpFunctionCall %v4float %foo_vf4_vf4_ %param %param_0
  580. OpStore %gl_FragColor %23
  581. OpReturn
  582. OpFunctionEnd
  583. )";
  584. const std::string func_before =
  585. R"(%foo_vf4_vf4_ = OpFunction %v4float None %17
  586. %v1 = OpFunctionParameter %_ptr_Function_v4float
  587. %v2 = OpFunctionParameter %_ptr_Function_v4float
  588. %24 = OpLabel
  589. %t = OpVariable %_ptr_Function_v4float Function
  590. %25 = OpLoad %v4float %v1
  591. %26 = OpFNegate %v4float %25
  592. OpStore %t %26
  593. %27 = OpLoad %v4float %v2
  594. OpReturnValue %27
  595. OpFunctionEnd
  596. )";
  597. const std::string func_after =
  598. R"(%foo_vf4_vf4_ = OpFunction %v4float None %17
  599. %v1 = OpFunctionParameter %_ptr_Function_v4float
  600. %v2 = OpFunctionParameter %_ptr_Function_v4float
  601. %24 = OpLabel
  602. %27 = OpLoad %v4float %v2
  603. OpReturnValue %27
  604. OpFunctionEnd
  605. )";
  606. SinglePassRunAndCheck<AggressiveDCEPass>(defs_before + func_before,
  607. defs_after + func_after, true, true);
  608. }
  609. TEST_F(AggressiveDCETest, ElimOpaque) {
  610. // SPIR-V not representable from GLSL; not generatable from HLSL
  611. // for the moment.
  612. const std::string defs_before =
  613. R"(OpCapability Shader
  614. %1 = OpExtInstImport "GLSL.std.450"
  615. OpMemoryModel Logical GLSL450
  616. OpEntryPoint Fragment %main "main" %outColor %texCoords
  617. OpExecutionMode %main OriginUpperLeft
  618. OpSource GLSL 140
  619. OpName %main "main"
  620. OpName %S_t "S_t"
  621. OpMemberName %S_t 0 "v0"
  622. OpMemberName %S_t 1 "v1"
  623. OpMemberName %S_t 2 "smp"
  624. OpName %outColor "outColor"
  625. OpName %sampler15 "sampler15"
  626. OpName %s0 "s0"
  627. OpName %texCoords "texCoords"
  628. OpDecorate %sampler15 DescriptorSet 0
  629. %void = OpTypeVoid
  630. %9 = OpTypeFunction %void
  631. %float = OpTypeFloat 32
  632. %v2float = OpTypeVector %float 2
  633. %v4float = OpTypeVector %float 4
  634. %_ptr_Output_v4float = OpTypePointer Output %v4float
  635. %outColor = OpVariable %_ptr_Output_v4float Output
  636. %14 = OpTypeImage %float 2D 0 0 0 1 Unknown
  637. %15 = OpTypeSampledImage %14
  638. %S_t = OpTypeStruct %v2float %v2float %15
  639. %_ptr_Function_S_t = OpTypePointer Function %S_t
  640. %17 = OpTypeFunction %void %_ptr_Function_S_t
  641. %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
  642. %_ptr_Function_15 = OpTypePointer Function %15
  643. %sampler15 = OpVariable %_ptr_UniformConstant_15 UniformConstant
  644. %int = OpTypeInt 32 1
  645. %int_0 = OpConstant %int 0
  646. %int_2 = OpConstant %int 2
  647. %_ptr_Function_v2float = OpTypePointer Function %v2float
  648. %_ptr_Input_v2float = OpTypePointer Input %v2float
  649. %texCoords = OpVariable %_ptr_Input_v2float Input
  650. )";
  651. const std::string defs_after =
  652. R"(OpCapability Shader
  653. %1 = OpExtInstImport "GLSL.std.450"
  654. OpMemoryModel Logical GLSL450
  655. OpEntryPoint Fragment %main "main" %outColor %texCoords
  656. OpExecutionMode %main OriginUpperLeft
  657. OpSource GLSL 140
  658. OpName %main "main"
  659. OpName %outColor "outColor"
  660. OpName %sampler15 "sampler15"
  661. OpName %texCoords "texCoords"
  662. OpDecorate %sampler15 DescriptorSet 0
  663. %void = OpTypeVoid
  664. %9 = OpTypeFunction %void
  665. %float = OpTypeFloat 32
  666. %v2float = OpTypeVector %float 2
  667. %v4float = OpTypeVector %float 4
  668. %_ptr_Output_v4float = OpTypePointer Output %v4float
  669. %outColor = OpVariable %_ptr_Output_v4float Output
  670. %14 = OpTypeImage %float 2D 0 0 0 1 Unknown
  671. %15 = OpTypeSampledImage %14
  672. %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
  673. %sampler15 = OpVariable %_ptr_UniformConstant_15 UniformConstant
  674. %_ptr_Input_v2float = OpTypePointer Input %v2float
  675. %texCoords = OpVariable %_ptr_Input_v2float Input
  676. )";
  677. const std::string func_before =
  678. R"(%main = OpFunction %void None %9
  679. %25 = OpLabel
  680. %s0 = OpVariable %_ptr_Function_S_t Function
  681. %26 = OpLoad %v2float %texCoords
  682. %27 = OpLoad %S_t %s0
  683. %28 = OpCompositeInsert %S_t %26 %27 0
  684. %29 = OpLoad %15 %sampler15
  685. %30 = OpCompositeInsert %S_t %29 %28 2
  686. OpStore %s0 %30
  687. %31 = OpImageSampleImplicitLod %v4float %29 %26
  688. OpStore %outColor %31
  689. OpReturn
  690. OpFunctionEnd
  691. )";
  692. const std::string func_after =
  693. R"(%main = OpFunction %void None %9
  694. %25 = OpLabel
  695. %26 = OpLoad %v2float %texCoords
  696. %29 = OpLoad %15 %sampler15
  697. %31 = OpImageSampleImplicitLod %v4float %29 %26
  698. OpStore %outColor %31
  699. OpReturn
  700. OpFunctionEnd
  701. )";
  702. SinglePassRunAndCheck<AggressiveDCEPass>(defs_before + func_before,
  703. defs_after + func_after, true, true);
  704. }
  705. TEST_F(AggressiveDCETest, NoParamStoreElim) {
  706. // Should not eliminate stores to params
  707. //
  708. // #version 450
  709. //
  710. // layout(location = 0) in vec4 BaseColor;
  711. // layout(location = 0) out vec4 OutColor;
  712. //
  713. // void foo(in vec4 v1, out vec4 v2)
  714. // {
  715. // v2 = -v1;
  716. // }
  717. //
  718. // void main()
  719. // {
  720. // foo(BaseColor, OutColor);
  721. // }
  722. const std::string assembly =
  723. R"(OpCapability Shader
  724. %1 = OpExtInstImport "GLSL.std.450"
  725. OpMemoryModel Logical GLSL450
  726. OpEntryPoint Fragment %main "main" %BaseColor %OutColor
  727. OpExecutionMode %main OriginUpperLeft
  728. OpSource GLSL 450
  729. OpName %main "main"
  730. OpName %foo_vf4_vf4_ "foo(vf4;vf4;"
  731. OpName %v1 "v1"
  732. OpName %v2 "v2"
  733. OpName %BaseColor "BaseColor"
  734. OpName %OutColor "OutColor"
  735. OpName %param "param"
  736. OpName %param_0 "param"
  737. OpDecorate %BaseColor Location 0
  738. OpDecorate %OutColor Location 0
  739. %void = OpTypeVoid
  740. %11 = OpTypeFunction %void
  741. %float = OpTypeFloat 32
  742. %v4float = OpTypeVector %float 4
  743. %_ptr_Function_v4float = OpTypePointer Function %v4float
  744. %15 = OpTypeFunction %void %_ptr_Function_v4float %_ptr_Function_v4float
  745. %_ptr_Input_v4float = OpTypePointer Input %v4float
  746. %BaseColor = OpVariable %_ptr_Input_v4float Input
  747. %_ptr_Output_v4float = OpTypePointer Output %v4float
  748. %OutColor = OpVariable %_ptr_Output_v4float Output
  749. %main = OpFunction %void None %11
  750. %18 = OpLabel
  751. %param = OpVariable %_ptr_Function_v4float Function
  752. %param_0 = OpVariable %_ptr_Function_v4float Function
  753. %19 = OpLoad %v4float %BaseColor
  754. OpStore %param %19
  755. %20 = OpFunctionCall %void %foo_vf4_vf4_ %param %param_0
  756. %21 = OpLoad %v4float %param_0
  757. OpStore %OutColor %21
  758. OpReturn
  759. OpFunctionEnd
  760. %foo_vf4_vf4_ = OpFunction %void None %15
  761. %v1 = OpFunctionParameter %_ptr_Function_v4float
  762. %v2 = OpFunctionParameter %_ptr_Function_v4float
  763. %22 = OpLabel
  764. %23 = OpLoad %v4float %v1
  765. %24 = OpFNegate %v4float %23
  766. OpStore %v2 %24
  767. OpReturn
  768. OpFunctionEnd
  769. )";
  770. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  771. }
  772. TEST_F(AggressiveDCETest, PrivateStoreElimInEntryNoCalls) {
  773. // Eliminate stores to private in entry point with no calls
  774. // Note: Not legal GLSL
  775. //
  776. // layout(location = 0) in vec4 BaseColor;
  777. // layout(location = 1) in vec4 Dead;
  778. // layout(location = 0) out vec4 OutColor;
  779. //
  780. // private vec4 dv;
  781. //
  782. // void main()
  783. // {
  784. // vec4 v = BaseColor;
  785. // dv = Dead;
  786. // OutColor = v;
  787. // }
  788. const std::string spirv =
  789. R"(OpCapability Shader
  790. %1 = OpExtInstImport "GLSL.std.450"
  791. OpMemoryModel Logical GLSL450
  792. OpEntryPoint Fragment %main "main" %BaseColor %Dead %OutColor
  793. OpExecutionMode %main OriginUpperLeft
  794. OpSource GLSL 450
  795. OpName %main "main"
  796. OpName %v "v"
  797. OpName %BaseColor "BaseColor"
  798. ; CHECK-NOT: OpName %dv "dv"
  799. OpName %dv "dv"
  800. OpName %Dead "Dead"
  801. OpName %OutColor "OutColor"
  802. OpDecorate %BaseColor Location 0
  803. OpDecorate %Dead Location 1
  804. OpDecorate %OutColor Location 0
  805. %void = OpTypeVoid
  806. %9 = OpTypeFunction %void
  807. %float = OpTypeFloat 32
  808. %v4float = OpTypeVector %float 4
  809. %_ptr_Function_v4float = OpTypePointer Function %v4float
  810. ; CHECK-NOT: OpTypePointer Private
  811. %_ptr_Private_v4float = OpTypePointer Private %v4float
  812. %_ptr_Input_v4float = OpTypePointer Input %v4float
  813. %BaseColor = OpVariable %_ptr_Input_v4float Input
  814. %Dead = OpVariable %_ptr_Input_v4float Input
  815. %_ptr_Output_v4float = OpTypePointer Output %v4float
  816. ; CHECK-NOT: %dv = OpVariable
  817. %dv = OpVariable %_ptr_Private_v4float Private
  818. %OutColor = OpVariable %_ptr_Output_v4float Output
  819. %main = OpFunction %void None %9
  820. %16 = OpLabel
  821. %v = OpVariable %_ptr_Function_v4float Function
  822. %17 = OpLoad %v4float %BaseColor
  823. OpStore %v %17
  824. %18 = OpLoad %v4float %Dead
  825. ; CHECK-NOT: OpStore %dv
  826. OpStore %dv %18
  827. %19 = OpLoad %v4float %v
  828. %20 = OpFNegate %v4float %19
  829. OpStore %OutColor %20
  830. OpReturn
  831. OpFunctionEnd
  832. )";
  833. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  834. }
  835. TEST_F(AggressiveDCETest, NoPrivateStoreElimIfLoad) {
  836. // Should not eliminate stores to private when there is a load
  837. // Note: Not legal GLSL
  838. //
  839. // #version 450
  840. //
  841. // layout(location = 0) in vec4 BaseColor;
  842. // layout(location = 0) out vec4 OutColor;
  843. //
  844. // private vec4 pv;
  845. //
  846. // void main()
  847. // {
  848. // pv = BaseColor;
  849. // OutColor = pv;
  850. // }
  851. const std::string assembly =
  852. R"(OpCapability Shader
  853. %1 = OpExtInstImport "GLSL.std.450"
  854. OpMemoryModel Logical GLSL450
  855. OpEntryPoint Fragment %main "main" %BaseColor %OutColor
  856. OpExecutionMode %main OriginUpperLeft
  857. OpSource GLSL 450
  858. OpName %main "main"
  859. OpName %pv "pv"
  860. OpName %BaseColor "BaseColor"
  861. OpName %OutColor "OutColor"
  862. OpDecorate %BaseColor Location 0
  863. OpDecorate %OutColor Location 0
  864. %void = OpTypeVoid
  865. %7 = OpTypeFunction %void
  866. %float = OpTypeFloat 32
  867. %v4float = OpTypeVector %float 4
  868. %_ptr_Private_v4float = OpTypePointer Private %v4float
  869. %_ptr_Input_v4float = OpTypePointer Input %v4float
  870. %BaseColor = OpVariable %_ptr_Input_v4float Input
  871. %_ptr_Output_v4float = OpTypePointer Output %v4float
  872. %OutColor = OpVariable %_ptr_Output_v4float Output
  873. %pv = OpVariable %_ptr_Private_v4float Private
  874. %main = OpFunction %void None %7
  875. %13 = OpLabel
  876. %14 = OpLoad %v4float %BaseColor
  877. OpStore %pv %14
  878. %15 = OpLoad %v4float %pv
  879. %16 = OpFNegate %v4float %15
  880. OpStore %OutColor %16
  881. OpReturn
  882. OpFunctionEnd
  883. )";
  884. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  885. }
  886. TEST_F(AggressiveDCETest, NoPrivateStoreElimWithCall) {
  887. // Should not eliminate stores to private when function contains call
  888. // Note: Not legal GLSL
  889. //
  890. // #version 450
  891. //
  892. // layout(location = 0) in vec4 BaseColor;
  893. // layout(location = 0) out vec4 OutColor;
  894. //
  895. // private vec4 v1;
  896. //
  897. // void foo()
  898. // {
  899. // OutColor = -v1;
  900. // }
  901. //
  902. // void main()
  903. // {
  904. // v1 = BaseColor;
  905. // foo();
  906. // }
  907. const std::string assembly =
  908. R"(OpCapability Shader
  909. %1 = OpExtInstImport "GLSL.std.450"
  910. OpMemoryModel Logical GLSL450
  911. OpEntryPoint Fragment %main "main" %OutColor %BaseColor
  912. OpExecutionMode %main OriginUpperLeft
  913. OpSource GLSL 450
  914. OpName %main "main"
  915. OpName %foo_ "foo("
  916. OpName %OutColor "OutColor"
  917. OpName %v1 "v1"
  918. OpName %BaseColor "BaseColor"
  919. OpDecorate %OutColor Location 0
  920. OpDecorate %BaseColor Location 0
  921. %void = OpTypeVoid
  922. %8 = OpTypeFunction %void
  923. %float = OpTypeFloat 32
  924. %v4float = OpTypeVector %float 4
  925. %_ptr_Output_v4float = OpTypePointer Output %v4float
  926. %OutColor = OpVariable %_ptr_Output_v4float Output
  927. %_ptr_Private_v4float = OpTypePointer Private %v4float
  928. %_ptr_Input_v4float = OpTypePointer Input %v4float
  929. %v1 = OpVariable %_ptr_Private_v4float Private
  930. %BaseColor = OpVariable %_ptr_Input_v4float Input
  931. %main = OpFunction %void None %8
  932. %14 = OpLabel
  933. %15 = OpLoad %v4float %BaseColor
  934. OpStore %v1 %15
  935. %16 = OpFunctionCall %void %foo_
  936. OpReturn
  937. OpFunctionEnd
  938. %foo_ = OpFunction %void None %8
  939. %17 = OpLabel
  940. %18 = OpLoad %v4float %v1
  941. %19 = OpFNegate %v4float %18
  942. OpStore %OutColor %19
  943. OpReturn
  944. OpFunctionEnd
  945. )";
  946. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  947. }
  948. TEST_F(AggressiveDCETest, NoPrivateStoreElimInNonEntry) {
  949. // Should not eliminate stores to private when function is not entry point
  950. // Note: Not legal GLSL
  951. //
  952. // #version 450
  953. //
  954. // layout(location = 0) in vec4 BaseColor;
  955. // layout(location = 0) out vec4 OutColor;
  956. //
  957. // private vec4 v1;
  958. //
  959. // void foo()
  960. // {
  961. // v1 = BaseColor;
  962. // }
  963. //
  964. // void main()
  965. // {
  966. // foo();
  967. // OutColor = -v1;
  968. // }
  969. const std::string assembly =
  970. R"(OpCapability Shader
  971. %1 = OpExtInstImport "GLSL.std.450"
  972. OpMemoryModel Logical GLSL450
  973. OpEntryPoint Fragment %main "main" %BaseColor %OutColor
  974. OpExecutionMode %main OriginUpperLeft
  975. OpSource GLSL 450
  976. OpName %main "main"
  977. OpName %foo_ "foo("
  978. OpName %v1 "v1"
  979. OpName %BaseColor "BaseColor"
  980. OpName %OutColor "OutColor"
  981. OpDecorate %BaseColor Location 0
  982. OpDecorate %OutColor Location 0
  983. %void = OpTypeVoid
  984. %8 = OpTypeFunction %void
  985. %float = OpTypeFloat 32
  986. %v4float = OpTypeVector %float 4
  987. %_ptr_Private_v4float = OpTypePointer Private %v4float
  988. %_ptr_Input_v4float = OpTypePointer Input %v4float
  989. %BaseColor = OpVariable %_ptr_Input_v4float Input
  990. %_ptr_Output_v4float = OpTypePointer Output %v4float
  991. %v1 = OpVariable %_ptr_Private_v4float Private
  992. %OutColor = OpVariable %_ptr_Output_v4float Output
  993. %main = OpFunction %void None %8
  994. %14 = OpLabel
  995. %15 = OpFunctionCall %void %foo_
  996. %16 = OpLoad %v4float %v1
  997. %17 = OpFNegate %v4float %16
  998. OpStore %OutColor %17
  999. OpReturn
  1000. OpFunctionEnd
  1001. %foo_ = OpFunction %void None %8
  1002. %18 = OpLabel
  1003. %19 = OpLoad %v4float %BaseColor
  1004. OpStore %v1 %19
  1005. OpReturn
  1006. OpFunctionEnd
  1007. )";
  1008. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  1009. }
  1010. TEST_F(AggressiveDCETest, WorkgroupStoreElimInEntryNoCalls) {
  1011. // Eliminate stores to private in entry point with no calls
  1012. // Note: Not legal GLSL
  1013. //
  1014. // layout(location = 0) in vec4 BaseColor;
  1015. // layout(location = 1) in vec4 Dead;
  1016. // layout(location = 0) out vec4 OutColor;
  1017. //
  1018. // workgroup vec4 dv;
  1019. //
  1020. // void main()
  1021. // {
  1022. // vec4 v = BaseColor;
  1023. // dv = Dead;
  1024. // OutColor = v;
  1025. // }
  1026. const std::string spirv =
  1027. R"(OpCapability Shader
  1028. %1 = OpExtInstImport "GLSL.std.450"
  1029. OpMemoryModel Logical GLSL450
  1030. OpEntryPoint Fragment %main "main" %BaseColor %Dead %OutColor
  1031. OpExecutionMode %main OriginUpperLeft
  1032. OpSource GLSL 450
  1033. OpName %main "main"
  1034. OpName %v "v"
  1035. OpName %BaseColor "BaseColor"
  1036. ; CHECK-NOT: OpName %dv "dv"
  1037. OpName %dv "dv"
  1038. OpName %Dead "Dead"
  1039. OpName %OutColor "OutColor"
  1040. OpDecorate %BaseColor Location 0
  1041. OpDecorate %Dead Location 1
  1042. OpDecorate %OutColor Location 0
  1043. %void = OpTypeVoid
  1044. %9 = OpTypeFunction %void
  1045. %float = OpTypeFloat 32
  1046. %v4float = OpTypeVector %float 4
  1047. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1048. ; CHECK-NOT: OpTypePointer Workgroup
  1049. %_ptr_Workgroup_v4float = OpTypePointer Workgroup %v4float
  1050. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1051. %BaseColor = OpVariable %_ptr_Input_v4float Input
  1052. %Dead = OpVariable %_ptr_Input_v4float Input
  1053. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1054. ; CHECK-NOT: %dv = OpVariable
  1055. %dv = OpVariable %_ptr_Workgroup_v4float Workgroup
  1056. %OutColor = OpVariable %_ptr_Output_v4float Output
  1057. %main = OpFunction %void None %9
  1058. %16 = OpLabel
  1059. %v = OpVariable %_ptr_Function_v4float Function
  1060. %17 = OpLoad %v4float %BaseColor
  1061. OpStore %v %17
  1062. %18 = OpLoad %v4float %Dead
  1063. ; CHECK-NOT: OpStore %dv
  1064. OpStore %dv %18
  1065. %19 = OpLoad %v4float %v
  1066. %20 = OpFNegate %v4float %19
  1067. OpStore %OutColor %20
  1068. OpReturn
  1069. OpFunctionEnd
  1070. )";
  1071. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  1072. }
  1073. TEST_F(AggressiveDCETest, EliminateDeadIfThenElse) {
  1074. // #version 450
  1075. //
  1076. // layout(location = 0) in vec4 BaseColor;
  1077. // layout(location = 0) out vec4 OutColor;
  1078. //
  1079. // void main()
  1080. // {
  1081. // float d;
  1082. // if (BaseColor.x == 0)
  1083. // d = BaseColor.y;
  1084. // else
  1085. // d = BaseColor.z;
  1086. // OutColor = vec4(1.0,1.0,1.0,1.0);
  1087. // }
  1088. const std::string spirv =
  1089. R"(OpCapability Shader
  1090. %1 = OpExtInstImport "GLSL.std.450"
  1091. OpMemoryModel Logical GLSL450
  1092. OpEntryPoint Fragment %main "main" %BaseColor %OutColor
  1093. OpExecutionMode %main OriginUpperLeft
  1094. OpSource GLSL 450
  1095. OpName %main "main"
  1096. OpName %BaseColor "BaseColor"
  1097. OpName %d "d"
  1098. OpName %OutColor "OutColor"
  1099. OpDecorate %BaseColor Location 0
  1100. OpDecorate %OutColor Location 0
  1101. %void = OpTypeVoid
  1102. %7 = OpTypeFunction %void
  1103. %float = OpTypeFloat 32
  1104. %v4float = OpTypeVector %float 4
  1105. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1106. %BaseColor = OpVariable %_ptr_Input_v4float Input
  1107. %uint = OpTypeInt 32 0
  1108. %uint_0 = OpConstant %uint 0
  1109. %_ptr_Input_float = OpTypePointer Input %float
  1110. %float_0 = OpConstant %float 0
  1111. %bool = OpTypeBool
  1112. %_ptr_Function_float = OpTypePointer Function %float
  1113. %uint_1 = OpConstant %uint 1
  1114. %uint_2 = OpConstant %uint 2
  1115. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1116. %OutColor = OpVariable %_ptr_Output_v4float Output
  1117. %float_1 = OpConstant %float 1
  1118. %21 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
  1119. ; CHECK: = OpFunction %void
  1120. ; CHECK-NEXT: %22 = OpLabel
  1121. ; CHECK-NEXT: OpBranch %26
  1122. ; CHECK-NEXT: %26 = OpLabel
  1123. %main = OpFunction %void None %7
  1124. %22 = OpLabel
  1125. %d = OpVariable %_ptr_Function_float Function
  1126. %23 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
  1127. %24 = OpLoad %float %23
  1128. %25 = OpFOrdEqual %bool %24 %float_0
  1129. OpSelectionMerge %26 None
  1130. OpBranchConditional %25 %27 %28
  1131. %27 = OpLabel
  1132. %29 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
  1133. %30 = OpLoad %float %29
  1134. OpStore %d %30
  1135. OpBranch %26
  1136. %28 = OpLabel
  1137. %31 = OpAccessChain %_ptr_Input_float %BaseColor %uint_2
  1138. %32 = OpLoad %float %31
  1139. OpStore %d %32
  1140. OpBranch %26
  1141. %26 = OpLabel
  1142. OpStore %OutColor %21
  1143. OpReturn
  1144. OpFunctionEnd
  1145. )";
  1146. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  1147. }
  1148. TEST_F(AggressiveDCETest, EliminateDeadIfThen) {
  1149. // #version 450
  1150. //
  1151. // layout(location = 0) in vec4 BaseColor;
  1152. // layout(location = 0) out vec4 OutColor;
  1153. //
  1154. // void main()
  1155. // {
  1156. // float d;
  1157. // if (BaseColor.x == 0)
  1158. // d = BaseColor.y;
  1159. // OutColor = vec4(1.0,1.0,1.0,1.0);
  1160. // }
  1161. const std::string spirv =
  1162. R"(OpCapability Shader
  1163. %1 = OpExtInstImport "GLSL.std.450"
  1164. OpMemoryModel Logical GLSL450
  1165. OpEntryPoint Fragment %main "main" %BaseColor %OutColor
  1166. OpExecutionMode %main OriginUpperLeft
  1167. OpSource GLSL 450
  1168. OpName %main "main"
  1169. OpName %BaseColor "BaseColor"
  1170. OpName %d "d"
  1171. OpName %OutColor "OutColor"
  1172. OpDecorate %BaseColor Location 0
  1173. OpDecorate %OutColor Location 0
  1174. %void = OpTypeVoid
  1175. %7 = OpTypeFunction %void
  1176. %float = OpTypeFloat 32
  1177. %v4float = OpTypeVector %float 4
  1178. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1179. %BaseColor = OpVariable %_ptr_Input_v4float Input
  1180. %uint = OpTypeInt 32 0
  1181. %uint_0 = OpConstant %uint 0
  1182. %_ptr_Input_float = OpTypePointer Input %float
  1183. %float_0 = OpConstant %float 0
  1184. %bool = OpTypeBool
  1185. %_ptr_Function_float = OpTypePointer Function %float
  1186. %uint_1 = OpConstant %uint 1
  1187. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1188. %OutColor = OpVariable %_ptr_Output_v4float Output
  1189. %float_1 = OpConstant %float 1
  1190. %20 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
  1191. ; CHECK: = OpFunction
  1192. ; CHECK-NEXT: %21 = OpLabel
  1193. ; CHECK-NEXT: OpBranch [[target:%\w+]]
  1194. ; CHECK-NEXT: [[target]] = OpLabel
  1195. %main = OpFunction %void None %7
  1196. %21 = OpLabel
  1197. %d = OpVariable %_ptr_Function_float Function
  1198. %22 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
  1199. %23 = OpLoad %float %22
  1200. %24 = OpFOrdEqual %bool %23 %float_0
  1201. OpSelectionMerge %25 None
  1202. OpBranchConditional %24 %26 %25
  1203. %26 = OpLabel
  1204. %27 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
  1205. %28 = OpLoad %float %27
  1206. OpStore %d %28
  1207. OpBranch %25
  1208. %25 = OpLabel
  1209. OpStore %OutColor %20
  1210. OpReturn
  1211. OpFunctionEnd
  1212. )";
  1213. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  1214. }
  1215. TEST_F(AggressiveDCETest, EliminateDeadSwitch) {
  1216. // #version 450
  1217. //
  1218. // layout(location = 0) in vec4 BaseColor;
  1219. // layout(location = 1) in flat int x;
  1220. // layout(location = 0) out vec4 OutColor;
  1221. //
  1222. // void main()
  1223. // {
  1224. // float d;
  1225. // switch (x) {
  1226. // case 0:
  1227. // d = BaseColor.y;
  1228. // }
  1229. // OutColor = vec4(1.0,1.0,1.0,1.0);
  1230. // }
  1231. const std::string spirv =
  1232. R"(OpCapability Shader
  1233. %1 = OpExtInstImport "GLSL.std.450"
  1234. OpMemoryModel Logical GLSL450
  1235. OpEntryPoint Fragment %main "main" %x %BaseColor %OutColor
  1236. OpExecutionMode %main OriginUpperLeft
  1237. OpSource GLSL 450
  1238. OpName %main "main"
  1239. OpName %x "x"
  1240. OpName %d "d"
  1241. OpName %BaseColor "BaseColor"
  1242. OpName %OutColor "OutColor"
  1243. OpDecorate %x Flat
  1244. OpDecorate %x Location 1
  1245. OpDecorate %BaseColor Location 0
  1246. OpDecorate %OutColor Location 0
  1247. %void = OpTypeVoid
  1248. %3 = OpTypeFunction %void
  1249. %int = OpTypeInt 32 1
  1250. %_ptr_Input_int = OpTypePointer Input %int
  1251. %x = OpVariable %_ptr_Input_int Input
  1252. %float = OpTypeFloat 32
  1253. %_ptr_Function_float = OpTypePointer Function %float
  1254. %v4float = OpTypeVector %float 4
  1255. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1256. %BaseColor = OpVariable %_ptr_Input_v4float Input
  1257. %uint = OpTypeInt 32 0
  1258. %uint_1 = OpConstant %uint 1
  1259. %_ptr_Input_float = OpTypePointer Input %float
  1260. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1261. %OutColor = OpVariable %_ptr_Output_v4float Output
  1262. %float_1 = OpConstant %float 1
  1263. %27 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
  1264. ; CHECK: = OpFunction
  1265. ; CHECK-NEXT: = OpLabel
  1266. ; CHECK-NEXT: OpBranch [[target:%\w+]]
  1267. ; CHECK-NEXT: [[target]] = OpLabel
  1268. %main = OpFunction %void None %3
  1269. %5 = OpLabel
  1270. %d = OpVariable %_ptr_Function_float Function
  1271. %9 = OpLoad %int %x
  1272. OpSelectionMerge %11 None
  1273. OpSwitch %9 %11 0 %10
  1274. %10 = OpLabel
  1275. %21 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
  1276. %22 = OpLoad %float %21
  1277. OpStore %d %22
  1278. OpBranch %11
  1279. %11 = OpLabel
  1280. OpStore %OutColor %27
  1281. OpReturn
  1282. OpFunctionEnd)";
  1283. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  1284. }
  1285. TEST_F(AggressiveDCETest, EliminateDeadIfThenElseNested) {
  1286. // #version 450
  1287. //
  1288. // layout(location = 0) in vec4 BaseColor;
  1289. // layout(location = 0) out vec4 OutColor;
  1290. //
  1291. // void main()
  1292. // {
  1293. // float d;
  1294. // if (BaseColor.x == 0)
  1295. // if (BaseColor.y == 0)
  1296. // d = 0.0;
  1297. // else
  1298. // d = 0.25;
  1299. // else
  1300. // if (BaseColor.y == 0)
  1301. // d = 0.5;
  1302. // else
  1303. // d = 0.75;
  1304. // OutColor = vec4(1.0,1.0,1.0,1.0);
  1305. // }
  1306. const std::string spirv =
  1307. R"(OpCapability Shader
  1308. %1 = OpExtInstImport "GLSL.std.450"
  1309. OpMemoryModel Logical GLSL450
  1310. OpEntryPoint Fragment %main "main" %BaseColor %OutColor
  1311. OpExecutionMode %main OriginUpperLeft
  1312. OpSource GLSL 450
  1313. OpName %main "main"
  1314. OpName %BaseColor "BaseColor"
  1315. OpName %d "d"
  1316. OpName %OutColor "OutColor"
  1317. OpDecorate %BaseColor Location 0
  1318. OpDecorate %OutColor Location 0
  1319. %void = OpTypeVoid
  1320. %7 = OpTypeFunction %void
  1321. %float = OpTypeFloat 32
  1322. %v4float = OpTypeVector %float 4
  1323. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1324. %BaseColor = OpVariable %_ptr_Input_v4float Input
  1325. %uint = OpTypeInt 32 0
  1326. %uint_0 = OpConstant %uint 0
  1327. %_ptr_Input_float = OpTypePointer Input %float
  1328. %float_0 = OpConstant %float 0
  1329. %bool = OpTypeBool
  1330. %uint_1 = OpConstant %uint 1
  1331. %_ptr_Function_float = OpTypePointer Function %float
  1332. %float_0_25 = OpConstant %float 0.25
  1333. %float_0_5 = OpConstant %float 0.5
  1334. %float_0_75 = OpConstant %float 0.75
  1335. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1336. %OutColor = OpVariable %_ptr_Output_v4float Output
  1337. %float_1 = OpConstant %float 1
  1338. %23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
  1339. ; CHECK: = OpFunction
  1340. ; CHECK-NEXT: = OpLabel
  1341. ; CHECK-NEXT: OpBranch [[target:%\w+]]
  1342. ; CHECK-NEXT: [[target]] = OpLabel
  1343. ; CHECK-NOT: OpLabel
  1344. %main = OpFunction %void None %7
  1345. %24 = OpLabel
  1346. %d = OpVariable %_ptr_Function_float Function
  1347. %25 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
  1348. %26 = OpLoad %float %25
  1349. %27 = OpFOrdEqual %bool %26 %float_0
  1350. OpSelectionMerge %28 None
  1351. OpBranchConditional %27 %29 %30
  1352. %29 = OpLabel
  1353. %31 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
  1354. %32 = OpLoad %float %31
  1355. %33 = OpFOrdEqual %bool %32 %float_0
  1356. OpSelectionMerge %34 None
  1357. OpBranchConditional %33 %35 %36
  1358. %35 = OpLabel
  1359. OpStore %d %float_0
  1360. OpBranch %34
  1361. %36 = OpLabel
  1362. OpStore %d %float_0_25
  1363. OpBranch %34
  1364. %34 = OpLabel
  1365. OpBranch %28
  1366. %30 = OpLabel
  1367. %37 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
  1368. %38 = OpLoad %float %37
  1369. %39 = OpFOrdEqual %bool %38 %float_0
  1370. OpSelectionMerge %40 None
  1371. OpBranchConditional %39 %41 %42
  1372. %41 = OpLabel
  1373. OpStore %d %float_0_5
  1374. OpBranch %40
  1375. %42 = OpLabel
  1376. OpStore %d %float_0_75
  1377. OpBranch %40
  1378. %40 = OpLabel
  1379. OpBranch %28
  1380. %28 = OpLabel
  1381. OpStore %OutColor %23
  1382. OpReturn
  1383. OpFunctionEnd
  1384. )";
  1385. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  1386. }
  1387. TEST_F(AggressiveDCETest, NoEliminateLiveIfThenElse) {
  1388. // #version 450
  1389. //
  1390. // layout(location = 0) in vec4 BaseColor;
  1391. // layout(location = 0) out vec4 OutColor;
  1392. //
  1393. // void main()
  1394. // {
  1395. // float t;
  1396. // if (BaseColor.x == 0)
  1397. // t = BaseColor.y;
  1398. // else
  1399. // t = BaseColor.z;
  1400. // OutColor = vec4(t);
  1401. // }
  1402. const std::string assembly =
  1403. R"(OpCapability Shader
  1404. %1 = OpExtInstImport "GLSL.std.450"
  1405. OpMemoryModel Logical GLSL450
  1406. OpEntryPoint Fragment %main "main" %BaseColor %OutColor
  1407. OpExecutionMode %main OriginUpperLeft
  1408. OpSource GLSL 450
  1409. OpName %main "main"
  1410. OpName %BaseColor "BaseColor"
  1411. OpName %t "t"
  1412. OpName %OutColor "OutColor"
  1413. OpDecorate %BaseColor Location 0
  1414. OpDecorate %OutColor Location 0
  1415. %void = OpTypeVoid
  1416. %7 = OpTypeFunction %void
  1417. %float = OpTypeFloat 32
  1418. %v4float = OpTypeVector %float 4
  1419. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1420. %BaseColor = OpVariable %_ptr_Input_v4float Input
  1421. %uint = OpTypeInt 32 0
  1422. %uint_0 = OpConstant %uint 0
  1423. %_ptr_Input_float = OpTypePointer Input %float
  1424. %float_0 = OpConstant %float 0
  1425. %bool = OpTypeBool
  1426. %_ptr_Function_float = OpTypePointer Function %float
  1427. %uint_1 = OpConstant %uint 1
  1428. %uint_2 = OpConstant %uint 2
  1429. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1430. %OutColor = OpVariable %_ptr_Output_v4float Output
  1431. %main = OpFunction %void None %7
  1432. %20 = OpLabel
  1433. %t = OpVariable %_ptr_Function_float Function
  1434. %21 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
  1435. %22 = OpLoad %float %21
  1436. %23 = OpFOrdEqual %bool %22 %float_0
  1437. OpSelectionMerge %24 None
  1438. OpBranchConditional %23 %25 %26
  1439. %25 = OpLabel
  1440. %27 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
  1441. %28 = OpLoad %float %27
  1442. OpStore %t %28
  1443. OpBranch %24
  1444. %26 = OpLabel
  1445. %29 = OpAccessChain %_ptr_Input_float %BaseColor %uint_2
  1446. %30 = OpLoad %float %29
  1447. OpStore %t %30
  1448. OpBranch %24
  1449. %24 = OpLabel
  1450. %31 = OpLoad %float %t
  1451. %32 = OpCompositeConstruct %v4float %31 %31 %31 %31
  1452. OpStore %OutColor %32
  1453. OpReturn
  1454. OpFunctionEnd
  1455. )";
  1456. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  1457. }
  1458. TEST_F(AggressiveDCETest, NoEliminateLiveIfThenElseNested) {
  1459. // #version 450
  1460. //
  1461. // layout(location = 0) in vec4 BaseColor;
  1462. // layout(location = 0) out vec4 OutColor;
  1463. //
  1464. // void main()
  1465. // {
  1466. // float t;
  1467. // if (BaseColor.x == 0)
  1468. // if (BaseColor.y == 0)
  1469. // t = 0.0;
  1470. // else
  1471. // t = 0.25;
  1472. // else
  1473. // if (BaseColor.y == 0)
  1474. // t = 0.5;
  1475. // else
  1476. // t = 0.75;
  1477. // OutColor = vec4(t);
  1478. // }
  1479. const std::string assembly =
  1480. R"(OpCapability Shader
  1481. %1 = OpExtInstImport "GLSL.std.450"
  1482. OpMemoryModel Logical GLSL450
  1483. OpEntryPoint Fragment %main "main" %BaseColor %OutColor
  1484. OpExecutionMode %main OriginUpperLeft
  1485. OpSource GLSL 450
  1486. OpName %main "main"
  1487. OpName %BaseColor "BaseColor"
  1488. OpName %t "t"
  1489. OpName %OutColor "OutColor"
  1490. OpDecorate %BaseColor Location 0
  1491. OpDecorate %OutColor Location 0
  1492. %void = OpTypeVoid
  1493. %7 = OpTypeFunction %void
  1494. %float = OpTypeFloat 32
  1495. %v4float = OpTypeVector %float 4
  1496. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1497. %BaseColor = OpVariable %_ptr_Input_v4float Input
  1498. %uint = OpTypeInt 32 0
  1499. %uint_0 = OpConstant %uint 0
  1500. %_ptr_Input_float = OpTypePointer Input %float
  1501. %float_0 = OpConstant %float 0
  1502. %bool = OpTypeBool
  1503. %uint_1 = OpConstant %uint 1
  1504. %_ptr_Function_float = OpTypePointer Function %float
  1505. %float_0_25 = OpConstant %float 0.25
  1506. %float_0_5 = OpConstant %float 0.5
  1507. %float_0_75 = OpConstant %float 0.75
  1508. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1509. %OutColor = OpVariable %_ptr_Output_v4float Output
  1510. %main = OpFunction %void None %7
  1511. %22 = OpLabel
  1512. %t = OpVariable %_ptr_Function_float Function
  1513. %23 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
  1514. %24 = OpLoad %float %23
  1515. %25 = OpFOrdEqual %bool %24 %float_0
  1516. OpSelectionMerge %26 None
  1517. OpBranchConditional %25 %27 %28
  1518. %27 = OpLabel
  1519. %29 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
  1520. %30 = OpLoad %float %29
  1521. %31 = OpFOrdEqual %bool %30 %float_0
  1522. OpSelectionMerge %32 None
  1523. OpBranchConditional %31 %33 %34
  1524. %33 = OpLabel
  1525. OpStore %t %float_0
  1526. OpBranch %32
  1527. %34 = OpLabel
  1528. OpStore %t %float_0_25
  1529. OpBranch %32
  1530. %32 = OpLabel
  1531. OpBranch %26
  1532. %28 = OpLabel
  1533. %35 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
  1534. %36 = OpLoad %float %35
  1535. %37 = OpFOrdEqual %bool %36 %float_0
  1536. OpSelectionMerge %38 None
  1537. OpBranchConditional %37 %39 %40
  1538. %39 = OpLabel
  1539. OpStore %t %float_0_5
  1540. OpBranch %38
  1541. %40 = OpLabel
  1542. OpStore %t %float_0_75
  1543. OpBranch %38
  1544. %38 = OpLabel
  1545. OpBranch %26
  1546. %26 = OpLabel
  1547. %41 = OpLoad %float %t
  1548. %42 = OpCompositeConstruct %v4float %41 %41 %41 %41
  1549. OpStore %OutColor %42
  1550. OpReturn
  1551. OpFunctionEnd
  1552. )";
  1553. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  1554. }
  1555. TEST_F(AggressiveDCETest, NoEliminateIfWithPhi) {
  1556. // Note: Assembly hand-optimized from GLSL
  1557. //
  1558. // #version 450
  1559. //
  1560. // layout(location = 0) in vec4 BaseColor;
  1561. // layout(location = 0) out vec4 OutColor;
  1562. //
  1563. // void main()
  1564. // {
  1565. // float t;
  1566. // if (BaseColor.x == 0)
  1567. // t = 0.0;
  1568. // else
  1569. // t = 1.0;
  1570. // OutColor = vec4(t);
  1571. // }
  1572. const std::string assembly =
  1573. R"(OpCapability Shader
  1574. %1 = OpExtInstImport "GLSL.std.450"
  1575. OpMemoryModel Logical GLSL450
  1576. OpEntryPoint Fragment %main "main" %BaseColor %OutColor
  1577. OpExecutionMode %main OriginUpperLeft
  1578. OpSource GLSL 450
  1579. OpName %main "main"
  1580. OpName %BaseColor "BaseColor"
  1581. OpName %OutColor "OutColor"
  1582. OpDecorate %BaseColor Location 0
  1583. OpDecorate %OutColor Location 0
  1584. %void = OpTypeVoid
  1585. %6 = OpTypeFunction %void
  1586. %float = OpTypeFloat 32
  1587. %v4float = OpTypeVector %float 4
  1588. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1589. %BaseColor = OpVariable %_ptr_Input_v4float Input
  1590. %uint = OpTypeInt 32 0
  1591. %uint_0 = OpConstant %uint 0
  1592. %_ptr_Input_float = OpTypePointer Input %float
  1593. %float_0 = OpConstant %float 0
  1594. %bool = OpTypeBool
  1595. %float_1 = OpConstant %float 1
  1596. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1597. %OutColor = OpVariable %_ptr_Output_v4float Output
  1598. %main = OpFunction %void None %6
  1599. %17 = OpLabel
  1600. %18 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
  1601. %19 = OpLoad %float %18
  1602. %20 = OpFOrdEqual %bool %19 %float_0
  1603. OpSelectionMerge %21 None
  1604. OpBranchConditional %20 %22 %23
  1605. %22 = OpLabel
  1606. OpBranch %21
  1607. %23 = OpLabel
  1608. OpBranch %21
  1609. %21 = OpLabel
  1610. %24 = OpPhi %float %float_0 %22 %float_1 %23
  1611. %25 = OpCompositeConstruct %v4float %24 %24 %24 %24
  1612. OpStore %OutColor %25
  1613. OpReturn
  1614. OpFunctionEnd
  1615. )";
  1616. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  1617. }
  1618. TEST_F(AggressiveDCETest, NoEliminateIfBreak) {
  1619. // Note: Assembly optimized from GLSL
  1620. //
  1621. // #version 450
  1622. //
  1623. // layout(location=0) in vec4 InColor;
  1624. // layout(location=0) out vec4 OutColor;
  1625. //
  1626. // void main()
  1627. // {
  1628. // float f = 0.0;
  1629. // for (;;) {
  1630. // f += 2.0;
  1631. // if (f > 20.0)
  1632. // break;
  1633. // }
  1634. //
  1635. // OutColor = InColor / f;
  1636. // }
  1637. const std::string assembly =
  1638. R"(OpCapability Shader
  1639. %1 = OpExtInstImport "GLSL.std.450"
  1640. OpMemoryModel Logical GLSL450
  1641. OpEntryPoint Fragment %main "main" %OutColor %InColor
  1642. OpExecutionMode %main OriginUpperLeft
  1643. OpSource GLSL 450
  1644. OpName %main "main"
  1645. OpName %f "f"
  1646. OpName %OutColor "OutColor"
  1647. OpName %InColor "InColor"
  1648. OpDecorate %OutColor Location 0
  1649. OpDecorate %InColor Location 0
  1650. %void = OpTypeVoid
  1651. %7 = OpTypeFunction %void
  1652. %float = OpTypeFloat 32
  1653. %_ptr_Function_float = OpTypePointer Function %float
  1654. %float_0 = OpConstant %float 0
  1655. %float_2 = OpConstant %float 2
  1656. %float_20 = OpConstant %float 20
  1657. %bool = OpTypeBool
  1658. %v4float = OpTypeVector %float 4
  1659. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1660. %OutColor = OpVariable %_ptr_Output_v4float Output
  1661. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1662. %InColor = OpVariable %_ptr_Input_v4float Input
  1663. %main = OpFunction %void None %7
  1664. %17 = OpLabel
  1665. %f = OpVariable %_ptr_Function_float Function
  1666. OpStore %f %float_0
  1667. OpBranch %18
  1668. %18 = OpLabel
  1669. OpLoopMerge %19 %20 None
  1670. OpBranch %21
  1671. %21 = OpLabel
  1672. %22 = OpLoad %float %f
  1673. %23 = OpFAdd %float %22 %float_2
  1674. OpStore %f %23
  1675. %24 = OpLoad %float %f
  1676. %25 = OpFOrdGreaterThan %bool %24 %float_20
  1677. OpSelectionMerge %26 None
  1678. OpBranchConditional %25 %27 %26
  1679. %27 = OpLabel
  1680. OpBranch %19
  1681. %26 = OpLabel
  1682. OpBranch %20
  1683. %20 = OpLabel
  1684. OpBranch %18
  1685. %19 = OpLabel
  1686. %28 = OpLoad %v4float %InColor
  1687. %29 = OpLoad %float %f
  1688. %30 = OpCompositeConstruct %v4float %29 %29 %29 %29
  1689. %31 = OpFDiv %v4float %28 %30
  1690. OpStore %OutColor %31
  1691. OpReturn
  1692. OpFunctionEnd
  1693. )";
  1694. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  1695. }
  1696. TEST_F(AggressiveDCETest, NoEliminateIfBreak2) {
  1697. // Do not eliminate break as conditional branch with merge instruction
  1698. // Note: SPIR-V edited to add merge instruction before break.
  1699. //
  1700. // #version 430
  1701. //
  1702. // layout(std430) buffer U_t
  1703. // {
  1704. // float g_F[10];
  1705. // };
  1706. //
  1707. // layout(location = 0)out float o;
  1708. //
  1709. // void main(void)
  1710. // {
  1711. // float s = 0.0;
  1712. // for (int i=0; i<10; i++)
  1713. // s += g_F[i];
  1714. // o = s;
  1715. // }
  1716. const std::string assembly =
  1717. R"(OpCapability Shader
  1718. %1 = OpExtInstImport "GLSL.std.450"
  1719. OpMemoryModel Logical GLSL450
  1720. OpEntryPoint Fragment %main "main" %o
  1721. OpExecutionMode %main OriginUpperLeft
  1722. OpSource GLSL 430
  1723. OpName %main "main"
  1724. OpName %s "s"
  1725. OpName %i "i"
  1726. OpName %U_t "U_t"
  1727. OpMemberName %U_t 0 "g_F"
  1728. OpName %_ ""
  1729. OpName %o "o"
  1730. OpDecorate %_arr_float_uint_10 ArrayStride 4
  1731. OpMemberDecorate %U_t 0 Offset 0
  1732. OpDecorate %U_t BufferBlock
  1733. OpDecorate %_ DescriptorSet 0
  1734. OpDecorate %o Location 0
  1735. %void = OpTypeVoid
  1736. %10 = OpTypeFunction %void
  1737. %float = OpTypeFloat 32
  1738. %_ptr_Function_float = OpTypePointer Function %float
  1739. %float_0 = OpConstant %float 0
  1740. %int = OpTypeInt 32 1
  1741. %_ptr_Function_int = OpTypePointer Function %int
  1742. %int_0 = OpConstant %int 0
  1743. %int_10 = OpConstant %int 10
  1744. %bool = OpTypeBool
  1745. %uint = OpTypeInt 32 0
  1746. %uint_10 = OpConstant %uint 10
  1747. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  1748. %U_t = OpTypeStruct %_arr_float_uint_10
  1749. %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
  1750. %_ = OpVariable %_ptr_Uniform_U_t Uniform
  1751. %_ptr_Uniform_float = OpTypePointer Uniform %float
  1752. %int_1 = OpConstant %int 1
  1753. %_ptr_Output_float = OpTypePointer Output %float
  1754. %o = OpVariable %_ptr_Output_float Output
  1755. %main = OpFunction %void None %10
  1756. %25 = OpLabel
  1757. %s = OpVariable %_ptr_Function_float Function
  1758. %i = OpVariable %_ptr_Function_int Function
  1759. OpStore %s %float_0
  1760. OpStore %i %int_0
  1761. OpBranch %26
  1762. %26 = OpLabel
  1763. OpLoopMerge %27 %28 None
  1764. OpBranch %29
  1765. %29 = OpLabel
  1766. %30 = OpLoad %int %i
  1767. %31 = OpSLessThan %bool %30 %int_10
  1768. OpSelectionMerge %32 None
  1769. OpBranchConditional %31 %32 %27
  1770. %32 = OpLabel
  1771. %33 = OpLoad %int %i
  1772. %34 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %33
  1773. %35 = OpLoad %float %34
  1774. %36 = OpLoad %float %s
  1775. %37 = OpFAdd %float %36 %35
  1776. OpStore %s %37
  1777. OpBranch %28
  1778. %28 = OpLabel
  1779. %38 = OpLoad %int %i
  1780. %39 = OpIAdd %int %38 %int_1
  1781. OpStore %i %39
  1782. OpBranch %26
  1783. %27 = OpLabel
  1784. %40 = OpLoad %float %s
  1785. OpStore %o %40
  1786. OpReturn
  1787. OpFunctionEnd
  1788. )";
  1789. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  1790. }
  1791. TEST_F(AggressiveDCETest, EliminateEntireUselessLoop) {
  1792. // #version 140
  1793. // in vec4 BaseColor;
  1794. //
  1795. // layout(std140) uniform U_t
  1796. // {
  1797. // int g_I ;
  1798. // } ;
  1799. //
  1800. // void main()
  1801. // {
  1802. // vec4 v = BaseColor;
  1803. // float df = 0.0;
  1804. // int i = 0;
  1805. // while (i < g_I) {
  1806. // df = df * 0.5;
  1807. // i = i + 1;
  1808. // }
  1809. // gl_FragColor = v;
  1810. // }
  1811. const std::string predefs1 =
  1812. R"(OpCapability Shader
  1813. %1 = OpExtInstImport "GLSL.std.450"
  1814. OpMemoryModel Logical GLSL450
  1815. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  1816. OpExecutionMode %main OriginUpperLeft
  1817. OpSource GLSL 140
  1818. )";
  1819. const std::string names_before =
  1820. R"(OpName %main "main"
  1821. OpName %v "v"
  1822. OpName %BaseColor "BaseColor"
  1823. OpName %df "df"
  1824. OpName %i "i"
  1825. OpName %U_t "U_t"
  1826. OpMemberName %U_t 0 "g_I"
  1827. OpName %_ ""
  1828. OpName %gl_FragColor "gl_FragColor"
  1829. )";
  1830. const std::string names_after =
  1831. R"(OpName %main "main"
  1832. OpName %v "v"
  1833. OpName %BaseColor "BaseColor"
  1834. OpName %gl_FragColor "gl_FragColor"
  1835. )";
  1836. const std::string predefs2_before =
  1837. R"(OpMemberDecorate %U_t 0 Offset 0
  1838. OpDecorate %U_t Block
  1839. OpDecorate %_ DescriptorSet 0
  1840. %void = OpTypeVoid
  1841. %11 = OpTypeFunction %void
  1842. %float = OpTypeFloat 32
  1843. %v4float = OpTypeVector %float 4
  1844. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1845. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1846. %BaseColor = OpVariable %_ptr_Input_v4float Input
  1847. %_ptr_Function_float = OpTypePointer Function %float
  1848. %float_0 = OpConstant %float 0
  1849. %int = OpTypeInt 32 1
  1850. %_ptr_Function_int = OpTypePointer Function %int
  1851. %int_0 = OpConstant %int 0
  1852. %U_t = OpTypeStruct %int
  1853. %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
  1854. %_ = OpVariable %_ptr_Uniform_U_t Uniform
  1855. %_ptr_Uniform_int = OpTypePointer Uniform %int
  1856. %bool = OpTypeBool
  1857. %float_0_5 = OpConstant %float 0.5
  1858. %int_1 = OpConstant %int 1
  1859. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1860. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  1861. )";
  1862. const std::string predefs2_after =
  1863. R"(%void = OpTypeVoid
  1864. %11 = OpTypeFunction %void
  1865. %float = OpTypeFloat 32
  1866. %v4float = OpTypeVector %float 4
  1867. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1868. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1869. %BaseColor = OpVariable %_ptr_Input_v4float Input
  1870. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1871. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  1872. )";
  1873. const std::string func_before =
  1874. R"(%main = OpFunction %void None %11
  1875. %27 = OpLabel
  1876. %v = OpVariable %_ptr_Function_v4float Function
  1877. %df = OpVariable %_ptr_Function_float Function
  1878. %i = OpVariable %_ptr_Function_int Function
  1879. %28 = OpLoad %v4float %BaseColor
  1880. OpStore %v %28
  1881. OpStore %df %float_0
  1882. OpStore %i %int_0
  1883. OpBranch %29
  1884. %29 = OpLabel
  1885. OpLoopMerge %30 %31 None
  1886. OpBranch %32
  1887. %32 = OpLabel
  1888. %33 = OpLoad %int %i
  1889. %34 = OpAccessChain %_ptr_Uniform_int %_ %int_0
  1890. %35 = OpLoad %int %34
  1891. %36 = OpSLessThan %bool %33 %35
  1892. OpBranchConditional %36 %37 %30
  1893. %37 = OpLabel
  1894. %38 = OpLoad %float %df
  1895. %39 = OpFMul %float %38 %float_0_5
  1896. OpStore %df %39
  1897. %40 = OpLoad %int %i
  1898. %41 = OpIAdd %int %40 %int_1
  1899. OpStore %i %41
  1900. OpBranch %31
  1901. %31 = OpLabel
  1902. OpBranch %29
  1903. %30 = OpLabel
  1904. %42 = OpLoad %v4float %v
  1905. OpStore %gl_FragColor %42
  1906. OpReturn
  1907. OpFunctionEnd
  1908. )";
  1909. const std::string func_after =
  1910. R"(%main = OpFunction %void None %11
  1911. %27 = OpLabel
  1912. %v = OpVariable %_ptr_Function_v4float Function
  1913. %28 = OpLoad %v4float %BaseColor
  1914. OpStore %v %28
  1915. OpBranch %29
  1916. %29 = OpLabel
  1917. OpBranch %30
  1918. %30 = OpLabel
  1919. %42 = OpLoad %v4float %v
  1920. OpStore %gl_FragColor %42
  1921. OpReturn
  1922. OpFunctionEnd
  1923. )";
  1924. SinglePassRunAndCheck<AggressiveDCEPass>(
  1925. predefs1 + names_before + predefs2_before + func_before,
  1926. predefs1 + names_after + predefs2_after + func_after, true, true);
  1927. }
  1928. TEST_F(AggressiveDCETest, NoEliminateBusyLoop) {
  1929. // Note: SPIR-V edited to replace AtomicAdd(i,0) with AtomicLoad(i)
  1930. //
  1931. // #version 450
  1932. //
  1933. // layout(std430) buffer I_t
  1934. // {
  1935. // int g_I;
  1936. // int g_I2;
  1937. // };
  1938. //
  1939. // layout(location = 0) out int o;
  1940. //
  1941. // void main(void)
  1942. // {
  1943. // while (atomicAdd(g_I, 0) == 0) {}
  1944. // o = g_I2;
  1945. // }
  1946. const std::string assembly =
  1947. R"(OpCapability Shader
  1948. %1 = OpExtInstImport "GLSL.std.450"
  1949. OpMemoryModel Logical GLSL450
  1950. OpEntryPoint Fragment %main "main" %o
  1951. OpExecutionMode %main OriginUpperLeft
  1952. OpSource GLSL 450
  1953. OpName %main "main"
  1954. OpName %I_t "I_t"
  1955. OpMemberName %I_t 0 "g_I"
  1956. OpMemberName %I_t 1 "g_I2"
  1957. OpName %_ ""
  1958. OpName %o "o"
  1959. OpMemberDecorate %I_t 0 Offset 0
  1960. OpMemberDecorate %I_t 1 Offset 4
  1961. OpDecorate %I_t BufferBlock
  1962. OpDecorate %_ DescriptorSet 0
  1963. OpDecorate %o Location 0
  1964. %void = OpTypeVoid
  1965. %7 = OpTypeFunction %void
  1966. %int = OpTypeInt 32 1
  1967. %I_t = OpTypeStruct %int %int
  1968. %_ptr_Uniform_I_t = OpTypePointer Uniform %I_t
  1969. %_ = OpVariable %_ptr_Uniform_I_t Uniform
  1970. %int_0 = OpConstant %int 0
  1971. %int_1 = OpConstant %int 1
  1972. %_ptr_Uniform_int = OpTypePointer Uniform %int
  1973. %uint = OpTypeInt 32 0
  1974. %uint_1 = OpConstant %uint 1
  1975. %uint_0 = OpConstant %uint 0
  1976. %bool = OpTypeBool
  1977. %_ptr_Output_int = OpTypePointer Output %int
  1978. %o = OpVariable %_ptr_Output_int Output
  1979. %main = OpFunction %void None %7
  1980. %18 = OpLabel
  1981. OpBranch %19
  1982. %19 = OpLabel
  1983. OpLoopMerge %20 %21 None
  1984. OpBranch %22
  1985. %22 = OpLabel
  1986. %23 = OpAccessChain %_ptr_Uniform_int %_ %int_0
  1987. %24 = OpAtomicLoad %int %23 %uint_1 %uint_0
  1988. %25 = OpIEqual %bool %24 %int_0
  1989. OpBranchConditional %25 %26 %20
  1990. %26 = OpLabel
  1991. OpBranch %21
  1992. %21 = OpLabel
  1993. OpBranch %19
  1994. %20 = OpLabel
  1995. %27 = OpAccessChain %_ptr_Uniform_int %_ %int_1
  1996. %28 = OpLoad %int %27
  1997. OpStore %o %28
  1998. OpReturn
  1999. OpFunctionEnd
  2000. )";
  2001. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  2002. }
  2003. TEST_F(AggressiveDCETest, NoEliminateLiveLoop) {
  2004. // Note: SPIR-V optimized
  2005. //
  2006. // #version 430
  2007. //
  2008. // layout(std430) buffer U_t
  2009. // {
  2010. // float g_F[10];
  2011. // };
  2012. //
  2013. // layout(location = 0)out float o;
  2014. //
  2015. // void main(void)
  2016. // {
  2017. // float s = 0.0;
  2018. // for (int i=0; i<10; i++)
  2019. // s += g_F[i];
  2020. // o = s;
  2021. // }
  2022. const std::string assembly =
  2023. R"(OpCapability Shader
  2024. %1 = OpExtInstImport "GLSL.std.450"
  2025. OpMemoryModel Logical GLSL450
  2026. OpEntryPoint Fragment %main "main" %o
  2027. OpExecutionMode %main OriginUpperLeft
  2028. OpSource GLSL 430
  2029. OpName %main "main"
  2030. OpName %U_t "U_t"
  2031. OpMemberName %U_t 0 "g_F"
  2032. OpName %_ ""
  2033. OpName %o "o"
  2034. OpDecorate %_arr_float_uint_10 ArrayStride 4
  2035. OpMemberDecorate %U_t 0 Offset 0
  2036. OpDecorate %U_t BufferBlock
  2037. OpDecorate %_ DescriptorSet 0
  2038. OpDecorate %o Location 0
  2039. %void = OpTypeVoid
  2040. %8 = OpTypeFunction %void
  2041. %float = OpTypeFloat 32
  2042. %float_0 = OpConstant %float 0
  2043. %int = OpTypeInt 32 1
  2044. %int_0 = OpConstant %int 0
  2045. %int_10 = OpConstant %int 10
  2046. %bool = OpTypeBool
  2047. %uint = OpTypeInt 32 0
  2048. %uint_10 = OpConstant %uint 10
  2049. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  2050. %U_t = OpTypeStruct %_arr_float_uint_10
  2051. %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
  2052. %_ = OpVariable %_ptr_Uniform_U_t Uniform
  2053. %_ptr_Uniform_float = OpTypePointer Uniform %float
  2054. %int_1 = OpConstant %int 1
  2055. %_ptr_Output_float = OpTypePointer Output %float
  2056. %o = OpVariable %_ptr_Output_float Output
  2057. %main = OpFunction %void None %8
  2058. %21 = OpLabel
  2059. OpBranch %22
  2060. %22 = OpLabel
  2061. %23 = OpPhi %float %float_0 %21 %24 %25
  2062. %26 = OpPhi %int %int_0 %21 %27 %25
  2063. OpLoopMerge %28 %25 None
  2064. OpBranch %29
  2065. %29 = OpLabel
  2066. %30 = OpSLessThan %bool %26 %int_10
  2067. OpBranchConditional %30 %31 %28
  2068. %31 = OpLabel
  2069. %32 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %26
  2070. %33 = OpLoad %float %32
  2071. %24 = OpFAdd %float %23 %33
  2072. OpBranch %25
  2073. %25 = OpLabel
  2074. %27 = OpIAdd %int %26 %int_1
  2075. OpBranch %22
  2076. %28 = OpLabel
  2077. OpStore %o %23
  2078. OpReturn
  2079. OpFunctionEnd
  2080. )";
  2081. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  2082. }
  2083. TEST_F(AggressiveDCETest, EliminateEntireFunctionBody) {
  2084. // #version 450
  2085. //
  2086. // layout(location = 0) in vec4 BaseColor;
  2087. // layout(location = 0) out vec4 OutColor;
  2088. //
  2089. // void main()
  2090. // {
  2091. // float d;
  2092. // if (BaseColor.x == 0)
  2093. // d = BaseColor.y;
  2094. // else
  2095. // d = BaseColor.z;
  2096. // }
  2097. const std::string spirv =
  2098. R"(OpCapability Shader
  2099. %1 = OpExtInstImport "GLSL.std.450"
  2100. OpMemoryModel Logical GLSL450
  2101. OpEntryPoint Fragment %main "main" %BaseColor %OutColor
  2102. OpExecutionMode %main OriginUpperLeft
  2103. OpSource GLSL 450
  2104. OpName %main "main"
  2105. OpName %BaseColor "BaseColor"
  2106. OpName %d "d"
  2107. OpName %OutColor "OutColor"
  2108. OpDecorate %BaseColor Location 0
  2109. OpDecorate %OutColor Location 0
  2110. %void = OpTypeVoid
  2111. %7 = OpTypeFunction %void
  2112. %float = OpTypeFloat 32
  2113. %v4float = OpTypeVector %float 4
  2114. %_ptr_Input_v4float = OpTypePointer Input %v4float
  2115. %BaseColor = OpVariable %_ptr_Input_v4float Input
  2116. %uint = OpTypeInt 32 0
  2117. %uint_0 = OpConstant %uint 0
  2118. %_ptr_Input_float = OpTypePointer Input %float
  2119. %float_0 = OpConstant %float 0
  2120. %bool = OpTypeBool
  2121. %_ptr_Function_float = OpTypePointer Function %float
  2122. %uint_1 = OpConstant %uint 1
  2123. %uint_2 = OpConstant %uint 2
  2124. %_ptr_Output_v4float = OpTypePointer Output %v4float
  2125. %OutColor = OpVariable %_ptr_Output_v4float Output
  2126. ; CHECK: = OpFunction
  2127. ; CHECK-NEXT: = OpLabel
  2128. ; CHECK-NEXT: OpBranch [[target:%\w+]]
  2129. ; CHECK-NEXT: [[target]] = OpLabel
  2130. ; CHECK-NEXT: OpReturn
  2131. ; CHECK-NEXT: OpFunctionEnd
  2132. %main = OpFunction %void None %7
  2133. %20 = OpLabel
  2134. %d = OpVariable %_ptr_Function_float Function
  2135. %21 = OpAccessChain %_ptr_Input_float %BaseColor %uint_0
  2136. %22 = OpLoad %float %21
  2137. %23 = OpFOrdEqual %bool %22 %float_0
  2138. OpSelectionMerge %24 None
  2139. OpBranchConditional %23 %25 %26
  2140. %25 = OpLabel
  2141. %27 = OpAccessChain %_ptr_Input_float %BaseColor %uint_1
  2142. %28 = OpLoad %float %27
  2143. OpStore %d %28
  2144. OpBranch %24
  2145. %26 = OpLabel
  2146. %29 = OpAccessChain %_ptr_Input_float %BaseColor %uint_2
  2147. %30 = OpLoad %float %29
  2148. OpStore %d %30
  2149. OpBranch %24
  2150. %24 = OpLabel
  2151. OpReturn
  2152. OpFunctionEnd
  2153. )";
  2154. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  2155. }
  2156. TEST_F(AggressiveDCETest, EliminateUselessInnerLoop) {
  2157. // #version 430
  2158. //
  2159. // layout(std430) buffer U_t
  2160. // {
  2161. // float g_F[10];
  2162. // };
  2163. //
  2164. // layout(location = 0)out float o;
  2165. //
  2166. // void main(void)
  2167. // {
  2168. // float s = 0.0;
  2169. // for (int i=0; i<10; i++) {
  2170. // for (int j=0; j<10; j++) {
  2171. // }
  2172. // s += g_F[i];
  2173. // }
  2174. // o = s;
  2175. // }
  2176. const std::string predefs_before =
  2177. R"(OpCapability Shader
  2178. %1 = OpExtInstImport "GLSL.std.450"
  2179. OpMemoryModel Logical GLSL450
  2180. OpEntryPoint Fragment %main "main" %o
  2181. OpExecutionMode %main OriginUpperLeft
  2182. OpSource GLSL 430
  2183. OpName %main "main"
  2184. OpName %s "s"
  2185. OpName %i "i"
  2186. OpName %j "j"
  2187. OpName %U_t "U_t"
  2188. OpMemberName %U_t 0 "g_F"
  2189. OpName %_ ""
  2190. OpName %o "o"
  2191. OpDecorate %_arr_float_uint_10 ArrayStride 4
  2192. OpMemberDecorate %U_t 0 Offset 0
  2193. OpDecorate %U_t BufferBlock
  2194. OpDecorate %_ DescriptorSet 0
  2195. OpDecorate %o Location 0
  2196. %void = OpTypeVoid
  2197. %11 = OpTypeFunction %void
  2198. %float = OpTypeFloat 32
  2199. %_ptr_Function_float = OpTypePointer Function %float
  2200. %float_0 = OpConstant %float 0
  2201. %int = OpTypeInt 32 1
  2202. %_ptr_Function_int = OpTypePointer Function %int
  2203. %int_0 = OpConstant %int 0
  2204. %int_10 = OpConstant %int 10
  2205. %bool = OpTypeBool
  2206. %int_1 = OpConstant %int 1
  2207. %uint = OpTypeInt 32 0
  2208. %uint_10 = OpConstant %uint 10
  2209. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  2210. %U_t = OpTypeStruct %_arr_float_uint_10
  2211. %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
  2212. %_ = OpVariable %_ptr_Uniform_U_t Uniform
  2213. %_ptr_Uniform_float = OpTypePointer Uniform %float
  2214. %_ptr_Output_float = OpTypePointer Output %float
  2215. %o = OpVariable %_ptr_Output_float Output
  2216. )";
  2217. const std::string predefs_after =
  2218. R"(OpCapability Shader
  2219. %1 = OpExtInstImport "GLSL.std.450"
  2220. OpMemoryModel Logical GLSL450
  2221. OpEntryPoint Fragment %main "main" %o
  2222. OpExecutionMode %main OriginUpperLeft
  2223. OpSource GLSL 430
  2224. OpName %main "main"
  2225. OpName %s "s"
  2226. OpName %i "i"
  2227. OpName %U_t "U_t"
  2228. OpMemberName %U_t 0 "g_F"
  2229. OpName %_ ""
  2230. OpName %o "o"
  2231. OpDecorate %_arr_float_uint_10 ArrayStride 4
  2232. OpMemberDecorate %U_t 0 Offset 0
  2233. OpDecorate %U_t BufferBlock
  2234. OpDecorate %_ DescriptorSet 0
  2235. OpDecorate %o Location 0
  2236. %void = OpTypeVoid
  2237. %11 = OpTypeFunction %void
  2238. %float = OpTypeFloat 32
  2239. %_ptr_Function_float = OpTypePointer Function %float
  2240. %float_0 = OpConstant %float 0
  2241. %int = OpTypeInt 32 1
  2242. %_ptr_Function_int = OpTypePointer Function %int
  2243. %int_0 = OpConstant %int 0
  2244. %int_10 = OpConstant %int 10
  2245. %bool = OpTypeBool
  2246. %int_1 = OpConstant %int 1
  2247. %uint = OpTypeInt 32 0
  2248. %uint_10 = OpConstant %uint 10
  2249. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  2250. %U_t = OpTypeStruct %_arr_float_uint_10
  2251. %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
  2252. %_ = OpVariable %_ptr_Uniform_U_t Uniform
  2253. %_ptr_Uniform_float = OpTypePointer Uniform %float
  2254. %_ptr_Output_float = OpTypePointer Output %float
  2255. %o = OpVariable %_ptr_Output_float Output
  2256. )";
  2257. const std::string func_before =
  2258. R"(%main = OpFunction %void None %11
  2259. %26 = OpLabel
  2260. %s = OpVariable %_ptr_Function_float Function
  2261. %i = OpVariable %_ptr_Function_int Function
  2262. %j = OpVariable %_ptr_Function_int Function
  2263. OpStore %s %float_0
  2264. OpStore %i %int_0
  2265. OpBranch %27
  2266. %27 = OpLabel
  2267. OpLoopMerge %28 %29 None
  2268. OpBranch %30
  2269. %30 = OpLabel
  2270. %31 = OpLoad %int %i
  2271. %32 = OpSLessThan %bool %31 %int_10
  2272. OpBranchConditional %32 %33 %28
  2273. %33 = OpLabel
  2274. OpStore %j %int_0
  2275. OpBranch %34
  2276. %34 = OpLabel
  2277. OpLoopMerge %35 %36 None
  2278. OpBranch %37
  2279. %37 = OpLabel
  2280. %38 = OpLoad %int %j
  2281. %39 = OpSLessThan %bool %38 %int_10
  2282. OpBranchConditional %39 %40 %35
  2283. %40 = OpLabel
  2284. OpBranch %36
  2285. %36 = OpLabel
  2286. %41 = OpLoad %int %j
  2287. %42 = OpIAdd %int %41 %int_1
  2288. OpStore %j %42
  2289. OpBranch %34
  2290. %35 = OpLabel
  2291. %43 = OpLoad %int %i
  2292. %44 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %43
  2293. %45 = OpLoad %float %44
  2294. %46 = OpLoad %float %s
  2295. %47 = OpFAdd %float %46 %45
  2296. OpStore %s %47
  2297. OpBranch %29
  2298. %29 = OpLabel
  2299. %48 = OpLoad %int %i
  2300. %49 = OpIAdd %int %48 %int_1
  2301. OpStore %i %49
  2302. OpBranch %27
  2303. %28 = OpLabel
  2304. %50 = OpLoad %float %s
  2305. OpStore %o %50
  2306. OpReturn
  2307. OpFunctionEnd
  2308. )";
  2309. const std::string func_after =
  2310. R"(%main = OpFunction %void None %11
  2311. %26 = OpLabel
  2312. %s = OpVariable %_ptr_Function_float Function
  2313. %i = OpVariable %_ptr_Function_int Function
  2314. OpStore %s %float_0
  2315. OpStore %i %int_0
  2316. OpBranch %27
  2317. %27 = OpLabel
  2318. OpLoopMerge %28 %29 None
  2319. OpBranch %30
  2320. %30 = OpLabel
  2321. %31 = OpLoad %int %i
  2322. %32 = OpSLessThan %bool %31 %int_10
  2323. OpBranchConditional %32 %33 %28
  2324. %33 = OpLabel
  2325. OpBranch %34
  2326. %34 = OpLabel
  2327. OpBranch %35
  2328. %35 = OpLabel
  2329. %43 = OpLoad %int %i
  2330. %44 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %43
  2331. %45 = OpLoad %float %44
  2332. %46 = OpLoad %float %s
  2333. %47 = OpFAdd %float %46 %45
  2334. OpStore %s %47
  2335. OpBranch %29
  2336. %29 = OpLabel
  2337. %48 = OpLoad %int %i
  2338. %49 = OpIAdd %int %48 %int_1
  2339. OpStore %i %49
  2340. OpBranch %27
  2341. %28 = OpLabel
  2342. %50 = OpLoad %float %s
  2343. OpStore %o %50
  2344. OpReturn
  2345. OpFunctionEnd
  2346. )";
  2347. SinglePassRunAndCheck<AggressiveDCEPass>(
  2348. predefs_before + func_before, predefs_after + func_after, true, true);
  2349. }
  2350. TEST_F(AggressiveDCETest, EliminateUselessNestedLoopWithIf) {
  2351. // #version 430
  2352. //
  2353. // layout(std430) buffer U_t
  2354. // {
  2355. // float g_F[10][10];
  2356. // };
  2357. //
  2358. // layout(location = 0)out float o;
  2359. //
  2360. // void main(void)
  2361. // {
  2362. // float s = 0.0;
  2363. // for (int i=0; i<10; i++) {
  2364. // for (int j=0; j<10; j++) {
  2365. // float t = g_F[i][j];
  2366. // if (t > 0.0)
  2367. // s += t;
  2368. // }
  2369. // }
  2370. // o = 0.0;
  2371. // }
  2372. const std::string predefs_before =
  2373. R"(OpCapability Shader
  2374. %1 = OpExtInstImport "GLSL.std.450"
  2375. OpMemoryModel Logical GLSL450
  2376. OpEntryPoint Fragment %main "main" %o
  2377. OpExecutionMode %main OriginUpperLeft
  2378. OpSource GLSL 430
  2379. OpName %main "main"
  2380. OpName %s "s"
  2381. OpName %i "i"
  2382. OpName %j "j"
  2383. OpName %U_t "U_t"
  2384. OpMemberName %U_t 0 "g_F"
  2385. OpName %_ ""
  2386. OpName %o "o"
  2387. OpDecorate %_arr_float_uint_10 ArrayStride 4
  2388. OpDecorate %_arr__arr_float_uint_10_uint_10 ArrayStride 40
  2389. OpMemberDecorate %U_t 0 Offset 0
  2390. OpDecorate %U_t BufferBlock
  2391. OpDecorate %_ DescriptorSet 0
  2392. OpDecorate %o Location 0
  2393. %void = OpTypeVoid
  2394. %12 = OpTypeFunction %void
  2395. %float = OpTypeFloat 32
  2396. %_ptr_Function_float = OpTypePointer Function %float
  2397. %float_0 = OpConstant %float 0
  2398. %int = OpTypeInt 32 1
  2399. %_ptr_Function_int = OpTypePointer Function %int
  2400. %int_0 = OpConstant %int 0
  2401. %int_10 = OpConstant %int 10
  2402. %bool = OpTypeBool
  2403. %uint = OpTypeInt 32 0
  2404. %uint_10 = OpConstant %uint 10
  2405. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  2406. %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
  2407. %U_t = OpTypeStruct %_arr__arr_float_uint_10_uint_10
  2408. %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
  2409. %_ = OpVariable %_ptr_Uniform_U_t Uniform
  2410. %_ptr_Uniform_float = OpTypePointer Uniform %float
  2411. %int_1 = OpConstant %int 1
  2412. %_ptr_Output_float = OpTypePointer Output %float
  2413. %o = OpVariable %_ptr_Output_float Output
  2414. )";
  2415. const std::string predefs_after =
  2416. R"(OpCapability Shader
  2417. %1 = OpExtInstImport "GLSL.std.450"
  2418. OpMemoryModel Logical GLSL450
  2419. OpEntryPoint Fragment %main "main" %o
  2420. OpExecutionMode %main OriginUpperLeft
  2421. OpSource GLSL 430
  2422. OpName %main "main"
  2423. OpName %o "o"
  2424. OpDecorate %o Location 0
  2425. %void = OpTypeVoid
  2426. %12 = OpTypeFunction %void
  2427. %float = OpTypeFloat 32
  2428. %float_0 = OpConstant %float 0
  2429. %_ptr_Output_float = OpTypePointer Output %float
  2430. %o = OpVariable %_ptr_Output_float Output
  2431. )";
  2432. const std::string func_before =
  2433. R"(%main = OpFunction %void None %12
  2434. %27 = OpLabel
  2435. %s = OpVariable %_ptr_Function_float Function
  2436. %i = OpVariable %_ptr_Function_int Function
  2437. %j = OpVariable %_ptr_Function_int Function
  2438. OpStore %s %float_0
  2439. OpStore %i %int_0
  2440. OpBranch %28
  2441. %28 = OpLabel
  2442. OpLoopMerge %29 %30 None
  2443. OpBranch %31
  2444. %31 = OpLabel
  2445. %32 = OpLoad %int %i
  2446. %33 = OpSLessThan %bool %32 %int_10
  2447. OpBranchConditional %33 %34 %29
  2448. %34 = OpLabel
  2449. OpStore %j %int_0
  2450. OpBranch %35
  2451. %35 = OpLabel
  2452. OpLoopMerge %36 %37 None
  2453. OpBranch %38
  2454. %38 = OpLabel
  2455. %39 = OpLoad %int %j
  2456. %40 = OpSLessThan %bool %39 %int_10
  2457. OpBranchConditional %40 %41 %36
  2458. %41 = OpLabel
  2459. %42 = OpLoad %int %i
  2460. %43 = OpLoad %int %j
  2461. %44 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %42 %43
  2462. %45 = OpLoad %float %44
  2463. %46 = OpFOrdGreaterThan %bool %45 %float_0
  2464. OpSelectionMerge %47 None
  2465. OpBranchConditional %46 %48 %47
  2466. %48 = OpLabel
  2467. %49 = OpLoad %float %s
  2468. %50 = OpFAdd %float %49 %45
  2469. OpStore %s %50
  2470. OpBranch %47
  2471. %47 = OpLabel
  2472. OpBranch %37
  2473. %37 = OpLabel
  2474. %51 = OpLoad %int %j
  2475. %52 = OpIAdd %int %51 %int_1
  2476. OpStore %j %52
  2477. OpBranch %35
  2478. %36 = OpLabel
  2479. OpBranch %30
  2480. %30 = OpLabel
  2481. %53 = OpLoad %int %i
  2482. %54 = OpIAdd %int %53 %int_1
  2483. OpStore %i %54
  2484. OpBranch %28
  2485. %29 = OpLabel
  2486. OpStore %o %float_0
  2487. OpReturn
  2488. OpFunctionEnd
  2489. )";
  2490. const std::string func_after =
  2491. R"(%main = OpFunction %void None %12
  2492. %27 = OpLabel
  2493. OpBranch %28
  2494. %28 = OpLabel
  2495. OpBranch %29
  2496. %29 = OpLabel
  2497. OpStore %o %float_0
  2498. OpReturn
  2499. OpFunctionEnd
  2500. )";
  2501. SinglePassRunAndCheck<AggressiveDCEPass>(
  2502. predefs_before + func_before, predefs_after + func_after, true, true);
  2503. }
  2504. TEST_F(AggressiveDCETest, EliminateEmptyIfBeforeContinue) {
  2505. // #version 430
  2506. //
  2507. // layout(location = 0)out float o;
  2508. //
  2509. // void main(void)
  2510. // {
  2511. // float s = 0.0;
  2512. // for (int i=0; i<10; i++) {
  2513. // s += 1.0;
  2514. // if (i > s) {}
  2515. // }
  2516. // o = s;
  2517. // }
  2518. const std::string predefs_before =
  2519. R"(OpCapability Shader
  2520. %1 = OpExtInstImport "GLSL.std.450"
  2521. OpMemoryModel Logical GLSL450
  2522. OpEntryPoint Fragment %main "main" %3
  2523. OpExecutionMode %main OriginUpperLeft
  2524. OpSource GLSL 430
  2525. OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
  2526. OpSourceExtension "GL_GOOGLE_include_directive"
  2527. OpName %main "main"
  2528. OpDecorate %3 Location 0
  2529. %void = OpTypeVoid
  2530. %5 = OpTypeFunction %void
  2531. %float = OpTypeFloat 32
  2532. %float_0 = OpConstant %float 0
  2533. %int = OpTypeInt 32 1
  2534. %_ptr_Function_int = OpTypePointer Function %int
  2535. %int_0 = OpConstant %int 0
  2536. %int_10 = OpConstant %int 10
  2537. %bool = OpTypeBool
  2538. %float_1 = OpConstant %float 1
  2539. %int_1 = OpConstant %int 1
  2540. %_ptr_Output_float = OpTypePointer Output %float
  2541. %3 = OpVariable %_ptr_Output_float Output
  2542. )";
  2543. const std::string predefs_after =
  2544. R"(OpCapability Shader
  2545. %1 = OpExtInstImport "GLSL.std.450"
  2546. OpMemoryModel Logical GLSL450
  2547. OpEntryPoint Fragment %main "main" %3
  2548. OpExecutionMode %main OriginUpperLeft
  2549. OpSource GLSL 430
  2550. OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
  2551. OpSourceExtension "GL_GOOGLE_include_directive"
  2552. OpName %main "main"
  2553. OpDecorate %3 Location 0
  2554. %void = OpTypeVoid
  2555. %5 = OpTypeFunction %void
  2556. %float = OpTypeFloat 32
  2557. %float_0 = OpConstant %float 0
  2558. %int = OpTypeInt 32 1
  2559. %int_0 = OpConstant %int 0
  2560. %int_10 = OpConstant %int 10
  2561. %bool = OpTypeBool
  2562. %float_1 = OpConstant %float 1
  2563. %int_1 = OpConstant %int 1
  2564. %_ptr_Output_float = OpTypePointer Output %float
  2565. %3 = OpVariable %_ptr_Output_float Output
  2566. )";
  2567. const std::string func_before =
  2568. R"(%main = OpFunction %void None %5
  2569. %16 = OpLabel
  2570. OpBranch %17
  2571. %17 = OpLabel
  2572. %18 = OpPhi %float %float_0 %16 %19 %20
  2573. %21 = OpPhi %int %int_0 %16 %22 %20
  2574. OpLoopMerge %23 %20 None
  2575. OpBranch %24
  2576. %24 = OpLabel
  2577. %25 = OpSLessThan %bool %21 %int_10
  2578. OpBranchConditional %25 %26 %23
  2579. %26 = OpLabel
  2580. %19 = OpFAdd %float %18 %float_1
  2581. %27 = OpConvertFToS %int %19
  2582. %28 = OpSGreaterThan %bool %21 %27
  2583. OpSelectionMerge %20 None
  2584. OpBranchConditional %28 %29 %20
  2585. %29 = OpLabel
  2586. OpBranch %20
  2587. %20 = OpLabel
  2588. %22 = OpIAdd %int %21 %int_1
  2589. OpBranch %17
  2590. %23 = OpLabel
  2591. OpStore %3 %18
  2592. OpReturn
  2593. OpFunctionEnd
  2594. )";
  2595. const std::string func_after =
  2596. R"(%main = OpFunction %void None %5
  2597. %16 = OpLabel
  2598. OpBranch %17
  2599. %17 = OpLabel
  2600. %18 = OpPhi %float %float_0 %16 %19 %20
  2601. %21 = OpPhi %int %int_0 %16 %22 %20
  2602. OpLoopMerge %23 %20 None
  2603. OpBranch %24
  2604. %24 = OpLabel
  2605. %25 = OpSLessThan %bool %21 %int_10
  2606. OpBranchConditional %25 %26 %23
  2607. %26 = OpLabel
  2608. %19 = OpFAdd %float %18 %float_1
  2609. OpBranch %20
  2610. %20 = OpLabel
  2611. %22 = OpIAdd %int %21 %int_1
  2612. OpBranch %17
  2613. %23 = OpLabel
  2614. OpStore %3 %18
  2615. OpReturn
  2616. OpFunctionEnd
  2617. )";
  2618. SinglePassRunAndCheck<AggressiveDCEPass>(
  2619. predefs_before + func_before, predefs_after + func_after, true, true);
  2620. }
  2621. TEST_F(AggressiveDCETest, NoEliminateLiveNestedLoopWithIf) {
  2622. // Note: SPIR-V optimized
  2623. //
  2624. // #version 430
  2625. //
  2626. // layout(std430) buffer U_t
  2627. // {
  2628. // float g_F[10][10];
  2629. // };
  2630. //
  2631. // layout(location = 0)out float o;
  2632. //
  2633. // void main(void)
  2634. // {
  2635. // float s = 0.0;
  2636. // for (int i=0; i<10; i++) {
  2637. // for (int j=0; j<10; j++) {
  2638. // float t = g_F[i][j];
  2639. // if (t > 0.0)
  2640. // s += t;
  2641. // }
  2642. // }
  2643. // o = s;
  2644. // }
  2645. const std::string assembly =
  2646. R"(OpCapability Shader
  2647. %1 = OpExtInstImport "GLSL.std.450"
  2648. OpMemoryModel Logical GLSL450
  2649. OpEntryPoint Fragment %main "main" %o
  2650. OpExecutionMode %main OriginUpperLeft
  2651. OpSource GLSL 430
  2652. OpName %main "main"
  2653. OpName %s "s"
  2654. OpName %i "i"
  2655. OpName %j "j"
  2656. OpName %U_t "U_t"
  2657. OpMemberName %U_t 0 "g_F"
  2658. OpName %_ ""
  2659. OpName %o "o"
  2660. OpDecorate %_arr_float_uint_10 ArrayStride 4
  2661. OpDecorate %_arr__arr_float_uint_10_uint_10 ArrayStride 40
  2662. OpMemberDecorate %U_t 0 Offset 0
  2663. OpDecorate %U_t BufferBlock
  2664. OpDecorate %_ DescriptorSet 0
  2665. OpDecorate %o Location 0
  2666. %void = OpTypeVoid
  2667. %12 = OpTypeFunction %void
  2668. %float = OpTypeFloat 32
  2669. %_ptr_Function_float = OpTypePointer Function %float
  2670. %float_0 = OpConstant %float 0
  2671. %int = OpTypeInt 32 1
  2672. %_ptr_Function_int = OpTypePointer Function %int
  2673. %int_0 = OpConstant %int 0
  2674. %int_10 = OpConstant %int 10
  2675. %bool = OpTypeBool
  2676. %uint = OpTypeInt 32 0
  2677. %uint_10 = OpConstant %uint 10
  2678. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  2679. %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
  2680. %U_t = OpTypeStruct %_arr__arr_float_uint_10_uint_10
  2681. %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
  2682. %_ = OpVariable %_ptr_Uniform_U_t Uniform
  2683. %_ptr_Uniform_float = OpTypePointer Uniform %float
  2684. %int_1 = OpConstant %int 1
  2685. %_ptr_Output_float = OpTypePointer Output %float
  2686. %o = OpVariable %_ptr_Output_float Output
  2687. %main = OpFunction %void None %12
  2688. %27 = OpLabel
  2689. %s = OpVariable %_ptr_Function_float Function
  2690. %i = OpVariable %_ptr_Function_int Function
  2691. %j = OpVariable %_ptr_Function_int Function
  2692. OpStore %s %float_0
  2693. OpStore %i %int_0
  2694. OpBranch %28
  2695. %28 = OpLabel
  2696. OpLoopMerge %29 %30 None
  2697. OpBranch %31
  2698. %31 = OpLabel
  2699. %32 = OpLoad %int %i
  2700. %33 = OpSLessThan %bool %32 %int_10
  2701. OpBranchConditional %33 %34 %29
  2702. %34 = OpLabel
  2703. OpStore %j %int_0
  2704. OpBranch %35
  2705. %35 = OpLabel
  2706. OpLoopMerge %36 %37 None
  2707. OpBranch %38
  2708. %38 = OpLabel
  2709. %39 = OpLoad %int %j
  2710. %40 = OpSLessThan %bool %39 %int_10
  2711. OpBranchConditional %40 %41 %36
  2712. %41 = OpLabel
  2713. %42 = OpLoad %int %i
  2714. %43 = OpLoad %int %j
  2715. %44 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %42 %43
  2716. %45 = OpLoad %float %44
  2717. %46 = OpFOrdGreaterThan %bool %45 %float_0
  2718. OpSelectionMerge %47 None
  2719. OpBranchConditional %46 %48 %47
  2720. %48 = OpLabel
  2721. %49 = OpLoad %float %s
  2722. %50 = OpFAdd %float %49 %45
  2723. OpStore %s %50
  2724. OpBranch %47
  2725. %47 = OpLabel
  2726. OpBranch %37
  2727. %37 = OpLabel
  2728. %51 = OpLoad %int %j
  2729. %52 = OpIAdd %int %51 %int_1
  2730. OpStore %j %52
  2731. OpBranch %35
  2732. %36 = OpLabel
  2733. OpBranch %30
  2734. %30 = OpLabel
  2735. %53 = OpLoad %int %i
  2736. %54 = OpIAdd %int %53 %int_1
  2737. OpStore %i %54
  2738. OpBranch %28
  2739. %29 = OpLabel
  2740. %55 = OpLoad %float %s
  2741. OpStore %o %55
  2742. OpReturn
  2743. OpFunctionEnd
  2744. )";
  2745. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  2746. }
  2747. TEST_F(AggressiveDCETest, NoEliminateIfContinue) {
  2748. // Do not eliminate continue embedded in if construct
  2749. //
  2750. // #version 430
  2751. //
  2752. // layout(std430) buffer U_t
  2753. // {
  2754. // float g_F[10];
  2755. // };
  2756. //
  2757. // layout(location = 0)out float o;
  2758. //
  2759. // void main(void)
  2760. // {
  2761. // float s = 0.0;
  2762. // for (int i=0; i<10; i++) {
  2763. // if (i % 2 == 0) continue;
  2764. // s += g_F[i];
  2765. // }
  2766. // o = s;
  2767. // }
  2768. const std::string assembly =
  2769. R"(OpCapability Shader
  2770. %1 = OpExtInstImport "GLSL.std.450"
  2771. OpMemoryModel Logical GLSL450
  2772. OpEntryPoint Fragment %main "main" %o
  2773. OpExecutionMode %main OriginUpperLeft
  2774. OpSource GLSL 430
  2775. OpName %main "main"
  2776. OpName %s "s"
  2777. OpName %i "i"
  2778. OpName %U_t "U_t"
  2779. OpMemberName %U_t 0 "g_F"
  2780. OpName %_ ""
  2781. OpName %o "o"
  2782. OpDecorate %_arr_float_uint_10 ArrayStride 4
  2783. OpMemberDecorate %U_t 0 Offset 0
  2784. OpDecorate %U_t BufferBlock
  2785. OpDecorate %_ DescriptorSet 0
  2786. OpDecorate %o Location 0
  2787. %void = OpTypeVoid
  2788. %10 = OpTypeFunction %void
  2789. %float = OpTypeFloat 32
  2790. %_ptr_Function_float = OpTypePointer Function %float
  2791. %float_0 = OpConstant %float 0
  2792. %int = OpTypeInt 32 1
  2793. %_ptr_Function_int = OpTypePointer Function %int
  2794. %int_0 = OpConstant %int 0
  2795. %int_10 = OpConstant %int 10
  2796. %bool = OpTypeBool
  2797. %int_2 = OpConstant %int 2
  2798. %uint = OpTypeInt 32 0
  2799. %uint_10 = OpConstant %uint 10
  2800. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  2801. %U_t = OpTypeStruct %_arr_float_uint_10
  2802. %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
  2803. %_ = OpVariable %_ptr_Uniform_U_t Uniform
  2804. %_ptr_Uniform_float = OpTypePointer Uniform %float
  2805. %int_1 = OpConstant %int 1
  2806. %_ptr_Output_float = OpTypePointer Output %float
  2807. %o = OpVariable %_ptr_Output_float Output
  2808. %main = OpFunction %void None %10
  2809. %26 = OpLabel
  2810. %s = OpVariable %_ptr_Function_float Function
  2811. %i = OpVariable %_ptr_Function_int Function
  2812. OpStore %s %float_0
  2813. OpStore %i %int_0
  2814. OpBranch %27
  2815. %27 = OpLabel
  2816. OpLoopMerge %28 %29 None
  2817. OpBranch %30
  2818. %30 = OpLabel
  2819. %31 = OpLoad %int %i
  2820. %32 = OpSLessThan %bool %31 %int_10
  2821. OpBranchConditional %32 %33 %28
  2822. %33 = OpLabel
  2823. %34 = OpLoad %int %i
  2824. %35 = OpSMod %int %34 %int_2
  2825. %36 = OpIEqual %bool %35 %int_0
  2826. OpSelectionMerge %37 None
  2827. OpBranchConditional %36 %38 %37
  2828. %38 = OpLabel
  2829. OpBranch %29
  2830. %37 = OpLabel
  2831. %39 = OpLoad %int %i
  2832. %40 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %39
  2833. %41 = OpLoad %float %40
  2834. %42 = OpLoad %float %s
  2835. %43 = OpFAdd %float %42 %41
  2836. OpStore %s %43
  2837. OpBranch %29
  2838. %29 = OpLabel
  2839. %44 = OpLoad %int %i
  2840. %45 = OpIAdd %int %44 %int_1
  2841. OpStore %i %45
  2842. OpBranch %27
  2843. %28 = OpLabel
  2844. %46 = OpLoad %float %s
  2845. OpStore %o %46
  2846. OpReturn
  2847. OpFunctionEnd
  2848. )";
  2849. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  2850. }
  2851. TEST_F(AggressiveDCETest, NoEliminateIfContinue2) {
  2852. // Do not eliminate continue not embedded in if construct
  2853. //
  2854. // #version 430
  2855. //
  2856. // layout(std430) buffer U_t
  2857. // {
  2858. // float g_F[10];
  2859. // };
  2860. //
  2861. // layout(location = 0)out float o;
  2862. //
  2863. // void main(void)
  2864. // {
  2865. // float s = 0.0;
  2866. // for (int i=0; i<10; i++) {
  2867. // if (i % 2 == 0) continue;
  2868. // s += g_F[i];
  2869. // }
  2870. // o = s;
  2871. // }
  2872. const std::string assembly =
  2873. R"(OpCapability Shader
  2874. %1 = OpExtInstImport "GLSL.std.450"
  2875. OpMemoryModel Logical GLSL450
  2876. OpEntryPoint Fragment %main "main" %o
  2877. OpExecutionMode %main OriginUpperLeft
  2878. OpSource GLSL 430
  2879. OpName %main "main"
  2880. OpName %s "s"
  2881. OpName %i "i"
  2882. OpName %U_t "U_t"
  2883. OpMemberName %U_t 0 "g_F"
  2884. OpName %_ ""
  2885. OpName %o "o"
  2886. OpDecorate %_arr_float_uint_10 ArrayStride 4
  2887. OpMemberDecorate %U_t 0 Offset 0
  2888. OpDecorate %U_t BufferBlock
  2889. OpDecorate %_ DescriptorSet 0
  2890. OpDecorate %o Location 0
  2891. %void = OpTypeVoid
  2892. %10 = OpTypeFunction %void
  2893. %float = OpTypeFloat 32
  2894. %_ptr_Function_float = OpTypePointer Function %float
  2895. %float_0 = OpConstant %float 0
  2896. %int = OpTypeInt 32 1
  2897. %_ptr_Function_int = OpTypePointer Function %int
  2898. %int_0 = OpConstant %int 0
  2899. %int_10 = OpConstant %int 10
  2900. %bool = OpTypeBool
  2901. %int_2 = OpConstant %int 2
  2902. %uint = OpTypeInt 32 0
  2903. %uint_10 = OpConstant %uint 10
  2904. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  2905. %U_t = OpTypeStruct %_arr_float_uint_10
  2906. %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
  2907. %_ = OpVariable %_ptr_Uniform_U_t Uniform
  2908. %_ptr_Uniform_float = OpTypePointer Uniform %float
  2909. %int_1 = OpConstant %int 1
  2910. %_ptr_Output_float = OpTypePointer Output %float
  2911. %o = OpVariable %_ptr_Output_float Output
  2912. %main = OpFunction %void None %10
  2913. %26 = OpLabel
  2914. %s = OpVariable %_ptr_Function_float Function
  2915. %i = OpVariable %_ptr_Function_int Function
  2916. OpStore %s %float_0
  2917. OpStore %i %int_0
  2918. OpBranch %27
  2919. %27 = OpLabel
  2920. OpLoopMerge %28 %29 None
  2921. OpBranch %30
  2922. %30 = OpLabel
  2923. %31 = OpLoad %int %i
  2924. %32 = OpSLessThan %bool %31 %int_10
  2925. OpBranchConditional %32 %33 %28
  2926. %33 = OpLabel
  2927. %34 = OpLoad %int %i
  2928. %35 = OpSMod %int %34 %int_2
  2929. %36 = OpIEqual %bool %35 %int_0
  2930. OpBranchConditional %36 %29 %37
  2931. %37 = OpLabel
  2932. %38 = OpLoad %int %i
  2933. %39 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %38
  2934. %40 = OpLoad %float %39
  2935. %41 = OpLoad %float %s
  2936. %42 = OpFAdd %float %41 %40
  2937. OpStore %s %42
  2938. OpBranch %29
  2939. %29 = OpLabel
  2940. %43 = OpLoad %int %i
  2941. %44 = OpIAdd %int %43 %int_1
  2942. OpStore %i %44
  2943. OpBranch %27
  2944. %28 = OpLabel
  2945. %45 = OpLoad %float %s
  2946. OpStore %o %45
  2947. OpReturn
  2948. OpFunctionEnd
  2949. )";
  2950. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  2951. }
  2952. TEST_F(AggressiveDCETest, NoEliminateIfContinue3) {
  2953. // Do not eliminate continue as conditional branch with merge instruction
  2954. // Note: SPIR-V edited to add merge instruction before continue.
  2955. //
  2956. // #version 430
  2957. //
  2958. // layout(std430) buffer U_t
  2959. // {
  2960. // float g_F[10];
  2961. // };
  2962. //
  2963. // layout(location = 0)out float o;
  2964. //
  2965. // void main(void)
  2966. // {
  2967. // float s = 0.0;
  2968. // for (int i=0; i<10; i++) {
  2969. // if (i % 2 == 0) continue;
  2970. // s += g_F[i];
  2971. // }
  2972. // o = s;
  2973. // }
  2974. const std::string assembly =
  2975. R"(OpCapability Shader
  2976. %1 = OpExtInstImport "GLSL.std.450"
  2977. OpMemoryModel Logical GLSL450
  2978. OpEntryPoint Fragment %main "main" %o
  2979. OpExecutionMode %main OriginUpperLeft
  2980. OpSource GLSL 430
  2981. OpName %main "main"
  2982. OpName %s "s"
  2983. OpName %i "i"
  2984. OpName %U_t "U_t"
  2985. OpMemberName %U_t 0 "g_F"
  2986. OpName %_ ""
  2987. OpName %o "o"
  2988. OpDecorate %_arr_float_uint_10 ArrayStride 4
  2989. OpMemberDecorate %U_t 0 Offset 0
  2990. OpDecorate %U_t BufferBlock
  2991. OpDecorate %_ DescriptorSet 0
  2992. OpDecorate %o Location 0
  2993. %void = OpTypeVoid
  2994. %10 = OpTypeFunction %void
  2995. %float = OpTypeFloat 32
  2996. %_ptr_Function_float = OpTypePointer Function %float
  2997. %float_0 = OpConstant %float 0
  2998. %int = OpTypeInt 32 1
  2999. %_ptr_Function_int = OpTypePointer Function %int
  3000. %int_0 = OpConstant %int 0
  3001. %int_10 = OpConstant %int 10
  3002. %bool = OpTypeBool
  3003. %int_2 = OpConstant %int 2
  3004. %uint = OpTypeInt 32 0
  3005. %uint_10 = OpConstant %uint 10
  3006. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  3007. %U_t = OpTypeStruct %_arr_float_uint_10
  3008. %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
  3009. %_ = OpVariable %_ptr_Uniform_U_t Uniform
  3010. %_ptr_Uniform_float = OpTypePointer Uniform %float
  3011. %int_1 = OpConstant %int 1
  3012. %_ptr_Output_float = OpTypePointer Output %float
  3013. %o = OpVariable %_ptr_Output_float Output
  3014. %main = OpFunction %void None %10
  3015. %26 = OpLabel
  3016. %s = OpVariable %_ptr_Function_float Function
  3017. %i = OpVariable %_ptr_Function_int Function
  3018. OpStore %s %float_0
  3019. OpStore %i %int_0
  3020. OpBranch %27
  3021. %27 = OpLabel
  3022. OpLoopMerge %28 %29 None
  3023. OpBranch %30
  3024. %30 = OpLabel
  3025. %31 = OpLoad %int %i
  3026. %32 = OpSLessThan %bool %31 %int_10
  3027. OpBranchConditional %32 %33 %28
  3028. %33 = OpLabel
  3029. %34 = OpLoad %int %i
  3030. %35 = OpSMod %int %34 %int_2
  3031. %36 = OpIEqual %bool %35 %int_0
  3032. OpSelectionMerge %37 None
  3033. OpBranchConditional %36 %29 %37
  3034. %37 = OpLabel
  3035. %38 = OpLoad %int %i
  3036. %39 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %38
  3037. %40 = OpLoad %float %39
  3038. %41 = OpLoad %float %s
  3039. %42 = OpFAdd %float %41 %40
  3040. OpStore %s %42
  3041. OpBranch %29
  3042. %29 = OpLabel
  3043. %43 = OpLoad %int %i
  3044. %44 = OpIAdd %int %43 %int_1
  3045. OpStore %i %44
  3046. OpBranch %27
  3047. %28 = OpLabel
  3048. %45 = OpLoad %float %s
  3049. OpStore %o %45
  3050. OpReturn
  3051. OpFunctionEnd
  3052. )";
  3053. SinglePassRunAndCheck<AggressiveDCEPass>(assembly, assembly, true, true);
  3054. }
  3055. // This is not valid input and ADCE does not support variable pointers and only
  3056. // supports shaders.
  3057. TEST_F(AggressiveDCETest, PointerVariable) {
  3058. // ADCE is able to handle code that contains a load whose base address
  3059. // comes from a load and not an OpVariable. I want to see an instruction
  3060. // removed to be sure that ADCE is not exiting early.
  3061. const std::string before =
  3062. R"(OpCapability Shader
  3063. OpMemoryModel Logical GLSL450
  3064. OpEntryPoint Fragment %1 "main" %2
  3065. OpExecutionMode %1 OriginUpperLeft
  3066. OpMemberDecorate %_struct_3 0 Offset 0
  3067. OpDecorate %_runtimearr__struct_3 ArrayStride 16
  3068. OpMemberDecorate %_struct_5 0 Offset 0
  3069. OpDecorate %_struct_5 BufferBlock
  3070. OpMemberDecorate %_struct_6 0 Offset 0
  3071. OpDecorate %_struct_6 BufferBlock
  3072. OpDecorate %2 Location 0
  3073. OpDecorate %7 DescriptorSet 0
  3074. OpDecorate %7 Binding 0
  3075. OpDecorate %8 DescriptorSet 0
  3076. OpDecorate %8 Binding 1
  3077. %void = OpTypeVoid
  3078. %10 = OpTypeFunction %void
  3079. %int = OpTypeInt 32 1
  3080. %uint = OpTypeInt 32 0
  3081. %float = OpTypeFloat 32
  3082. %v4float = OpTypeVector %float 4
  3083. %_ptr_Output_v4float = OpTypePointer Output %v4float
  3084. %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
  3085. %_struct_3 = OpTypeStruct %v4float
  3086. %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
  3087. %_struct_5 = OpTypeStruct %_runtimearr__struct_3
  3088. %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
  3089. %_struct_6 = OpTypeStruct %int
  3090. %_ptr_Uniform__struct_6 = OpTypePointer Uniform %_struct_6
  3091. %_ptr_Function__ptr_Uniform__struct_5 = OpTypePointer Function %_ptr_Uniform__struct_5
  3092. %_ptr_Function__ptr_Uniform__struct_6 = OpTypePointer Function %_ptr_Uniform__struct_6
  3093. %int_0 = OpConstant %int 0
  3094. %uint_0 = OpConstant %uint 0
  3095. %2 = OpVariable %_ptr_Output_v4float Output
  3096. %7 = OpVariable %_ptr_Uniform__struct_5 Uniform
  3097. %8 = OpVariable %_ptr_Uniform__struct_6 Uniform
  3098. %1 = OpFunction %void None %10
  3099. %23 = OpLabel
  3100. %24 = OpVariable %_ptr_Function__ptr_Uniform__struct_5 Function
  3101. OpStore %24 %7
  3102. %26 = OpLoad %_ptr_Uniform__struct_5 %24
  3103. %27 = OpAccessChain %_ptr_Uniform_v4float %26 %int_0 %uint_0 %int_0
  3104. %28 = OpLoad %v4float %27
  3105. %29 = OpCopyObject %v4float %28
  3106. OpStore %2 %28
  3107. OpReturn
  3108. OpFunctionEnd
  3109. )";
  3110. const std::string after =
  3111. R"(OpCapability Shader
  3112. OpMemoryModel Logical GLSL450
  3113. OpEntryPoint Fragment %1 "main" %2
  3114. OpExecutionMode %1 OriginUpperLeft
  3115. OpMemberDecorate %_struct_3 0 Offset 0
  3116. OpDecorate %_runtimearr__struct_3 ArrayStride 16
  3117. OpMemberDecorate %_struct_5 0 Offset 0
  3118. OpDecorate %_struct_5 BufferBlock
  3119. OpDecorate %2 Location 0
  3120. OpDecorate %7 DescriptorSet 0
  3121. OpDecorate %7 Binding 0
  3122. %void = OpTypeVoid
  3123. %10 = OpTypeFunction %void
  3124. %int = OpTypeInt 32 1
  3125. %uint = OpTypeInt 32 0
  3126. %float = OpTypeFloat 32
  3127. %v4float = OpTypeVector %float 4
  3128. %_ptr_Output_v4float = OpTypePointer Output %v4float
  3129. %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
  3130. %_struct_3 = OpTypeStruct %v4float
  3131. %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
  3132. %_struct_5 = OpTypeStruct %_runtimearr__struct_3
  3133. %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
  3134. %_ptr_Function__ptr_Uniform__struct_5 = OpTypePointer Function %_ptr_Uniform__struct_5
  3135. %int_0 = OpConstant %int 0
  3136. %uint_0 = OpConstant %uint 0
  3137. %2 = OpVariable %_ptr_Output_v4float Output
  3138. %7 = OpVariable %_ptr_Uniform__struct_5 Uniform
  3139. %1 = OpFunction %void None %10
  3140. %23 = OpLabel
  3141. %24 = OpVariable %_ptr_Function__ptr_Uniform__struct_5 Function
  3142. OpStore %24 %7
  3143. %25 = OpLoad %_ptr_Uniform__struct_5 %24
  3144. %26 = OpAccessChain %_ptr_Uniform_v4float %25 %int_0 %uint_0 %int_0
  3145. %27 = OpLoad %v4float %26
  3146. OpStore %2 %27
  3147. OpReturn
  3148. OpFunctionEnd
  3149. )";
  3150. // The input is not valid and ADCE only supports shaders, but not variable
  3151. // pointers. Workaround this by enabling relaxed logical pointers in the
  3152. // validator.
  3153. ValidatorOptions()->relax_logical_pointer = true;
  3154. SinglePassRunAndCheck<AggressiveDCEPass>(before, after, true, true);
  3155. }
  3156. // %dead is unused. Make sure we remove it along with its name.
  3157. TEST_F(AggressiveDCETest, RemoveUnreferenced) {
  3158. const std::string before =
  3159. R"(OpCapability Shader
  3160. OpCapability Linkage
  3161. %1 = OpExtInstImport "GLSL.std.450"
  3162. OpMemoryModel Logical GLSL450
  3163. OpEntryPoint Fragment %main "main"
  3164. OpExecutionMode %main OriginUpperLeft
  3165. OpSource GLSL 150
  3166. OpName %main "main"
  3167. OpName %dead "dead"
  3168. %void = OpTypeVoid
  3169. %5 = OpTypeFunction %void
  3170. %float = OpTypeFloat 32
  3171. %_ptr_Private_float = OpTypePointer Private %float
  3172. %dead = OpVariable %_ptr_Private_float Private
  3173. %main = OpFunction %void None %5
  3174. %8 = OpLabel
  3175. OpReturn
  3176. OpFunctionEnd
  3177. )";
  3178. const std::string after =
  3179. R"(OpCapability Shader
  3180. OpCapability Linkage
  3181. %1 = OpExtInstImport "GLSL.std.450"
  3182. OpMemoryModel Logical GLSL450
  3183. OpEntryPoint Fragment %main "main"
  3184. OpExecutionMode %main OriginUpperLeft
  3185. OpSource GLSL 150
  3186. OpName %main "main"
  3187. %void = OpTypeVoid
  3188. %5 = OpTypeFunction %void
  3189. %main = OpFunction %void None %5
  3190. %8 = OpLabel
  3191. OpReturn
  3192. OpFunctionEnd
  3193. )";
  3194. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  3195. SinglePassRunAndCheck<AggressiveDCEPass>(before, after, true, true);
  3196. }
  3197. // Delete %dead because it is unreferenced. Then %initializer becomes
  3198. // unreferenced, so remove it as well.
  3199. TEST_F(AggressiveDCETest, RemoveUnreferencedWithInit1) {
  3200. const std::string before =
  3201. R"(OpCapability Shader
  3202. OpCapability Linkage
  3203. %1 = OpExtInstImport "GLSL.std.450"
  3204. OpMemoryModel Logical GLSL450
  3205. OpEntryPoint Fragment %main "main"
  3206. OpExecutionMode %main OriginUpperLeft
  3207. OpSource GLSL 150
  3208. OpName %main "main"
  3209. OpName %dead "dead"
  3210. OpName %initializer "initializer"
  3211. %void = OpTypeVoid
  3212. %6 = OpTypeFunction %void
  3213. %float = OpTypeFloat 32
  3214. %_ptr_Private_float = OpTypePointer Private %float
  3215. %initializer = OpVariable %_ptr_Private_float Private
  3216. %dead = OpVariable %_ptr_Private_float Private %initializer
  3217. %main = OpFunction %void None %6
  3218. %9 = OpLabel
  3219. OpReturn
  3220. OpFunctionEnd
  3221. )";
  3222. const std::string after =
  3223. R"(OpCapability Shader
  3224. OpCapability Linkage
  3225. %1 = OpExtInstImport "GLSL.std.450"
  3226. OpMemoryModel Logical GLSL450
  3227. OpEntryPoint Fragment %main "main"
  3228. OpExecutionMode %main OriginUpperLeft
  3229. OpSource GLSL 150
  3230. OpName %main "main"
  3231. %void = OpTypeVoid
  3232. %6 = OpTypeFunction %void
  3233. %main = OpFunction %void None %6
  3234. %9 = OpLabel
  3235. OpReturn
  3236. OpFunctionEnd
  3237. )";
  3238. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  3239. SinglePassRunAndCheck<AggressiveDCEPass>(before, after, true, true);
  3240. }
  3241. // Keep %live because it is used, and its initializer.
  3242. TEST_F(AggressiveDCETest, KeepReferenced) {
  3243. const std::string before =
  3244. R"(OpCapability Shader
  3245. OpCapability Linkage
  3246. %1 = OpExtInstImport "GLSL.std.450"
  3247. OpMemoryModel Logical GLSL450
  3248. OpEntryPoint Fragment %main "main" %output
  3249. OpExecutionMode %main OriginUpperLeft
  3250. OpSource GLSL 150
  3251. OpName %main "main"
  3252. OpName %live "live"
  3253. OpName %initializer "initializer"
  3254. OpName %output "output"
  3255. %void = OpTypeVoid
  3256. %6 = OpTypeFunction %void
  3257. %float = OpTypeFloat 32
  3258. %_ptr_Private_float = OpTypePointer Private %float
  3259. %initializer = OpConstant %float 0
  3260. %live = OpVariable %_ptr_Private_float Private %initializer
  3261. %_ptr_Output_float = OpTypePointer Output %float
  3262. %output = OpVariable %_ptr_Output_float Output
  3263. %main = OpFunction %void None %6
  3264. %9 = OpLabel
  3265. %10 = OpLoad %float %live
  3266. OpStore %output %10
  3267. OpReturn
  3268. OpFunctionEnd
  3269. )";
  3270. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  3271. SinglePassRunAndCheck<AggressiveDCEPass>(before, before, true, true);
  3272. }
  3273. // This test that the decoration associated with a variable are removed when the
  3274. // variable is removed.
  3275. TEST_F(AggressiveDCETest, RemoveVariableAndDecorations) {
  3276. const std::string before =
  3277. R"(OpCapability Shader
  3278. %1 = OpExtInstImport "GLSL.std.450"
  3279. OpMemoryModel Logical GLSL450
  3280. OpEntryPoint Vertex %main "main"
  3281. OpSource GLSL 450
  3282. OpName %main "main"
  3283. OpName %B "B"
  3284. OpMemberName %B 0 "a"
  3285. OpName %Bdat "Bdat"
  3286. OpMemberDecorate %B 0 Offset 0
  3287. OpDecorate %B BufferBlock
  3288. OpDecorate %Bdat DescriptorSet 0
  3289. OpDecorate %Bdat Binding 0
  3290. %void = OpTypeVoid
  3291. %6 = OpTypeFunction %void
  3292. %uint = OpTypeInt 32 0
  3293. %B = OpTypeStruct %uint
  3294. %_ptr_Uniform_B = OpTypePointer Uniform %B
  3295. %Bdat = OpVariable %_ptr_Uniform_B Uniform
  3296. %int = OpTypeInt 32 1
  3297. %int_0 = OpConstant %int 0
  3298. %uint_1 = OpConstant %uint 1
  3299. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  3300. %main = OpFunction %void None %6
  3301. %13 = OpLabel
  3302. OpReturn
  3303. OpFunctionEnd
  3304. )";
  3305. const std::string after =
  3306. R"(OpCapability Shader
  3307. %1 = OpExtInstImport "GLSL.std.450"
  3308. OpMemoryModel Logical GLSL450
  3309. OpEntryPoint Vertex %main "main"
  3310. OpSource GLSL 450
  3311. OpName %main "main"
  3312. %void = OpTypeVoid
  3313. %6 = OpTypeFunction %void
  3314. %main = OpFunction %void None %6
  3315. %13 = OpLabel
  3316. OpReturn
  3317. OpFunctionEnd
  3318. )";
  3319. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  3320. SinglePassRunAndCheck<AggressiveDCEPass>(before, after, true, true);
  3321. }
  3322. TEST_F(AggressiveDCETest, DeadNestedSwitch) {
  3323. const std::string text = R"(
  3324. ; CHECK: OpLabel
  3325. ; CHECK: OpBranch [[block:%\w+]]
  3326. ; CHECK-NOT: OpSwitch
  3327. ; CHECK-NEXT: [[block]] = OpLabel
  3328. ; CHECK: OpBranch [[block:%\w+]]
  3329. ; CHECK-NOT: OpSwitch
  3330. ; CHECK-NEXT: [[block]] = OpLabel
  3331. ; CHECK-NEXT: OpStore
  3332. OpCapability Shader
  3333. OpMemoryModel Logical GLSL450
  3334. OpEntryPoint Fragment %func "func" %x
  3335. OpExecutionMode %func OriginUpperLeft
  3336. OpName %func "func"
  3337. %void = OpTypeVoid
  3338. %1 = OpTypeFunction %void
  3339. %uint = OpTypeInt 32 0
  3340. %uint_0 = OpConstant %uint 0
  3341. %uint_ptr_Output = OpTypePointer Output %uint
  3342. %uint_ptr_Input = OpTypePointer Input %uint
  3343. %x = OpVariable %uint_ptr_Output Output
  3344. %a = OpVariable %uint_ptr_Input Input
  3345. %func = OpFunction %void None %1
  3346. %entry = OpLabel
  3347. OpBranch %header
  3348. %header = OpLabel
  3349. %ld = OpLoad %uint %a
  3350. OpLoopMerge %merge %continue None
  3351. OpBranch %postheader
  3352. %postheader = OpLabel
  3353. ; This switch doesn't require an OpSelectionMerge and is nested in the dead loop.
  3354. OpSwitch %ld %merge 0 %extra 1 %continue
  3355. %extra = OpLabel
  3356. OpBranch %continue
  3357. %continue = OpLabel
  3358. OpBranch %header
  3359. %merge = OpLabel
  3360. OpStore %x %uint_0
  3361. OpReturn
  3362. OpFunctionEnd
  3363. )";
  3364. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  3365. }
  3366. TEST_F(AggressiveDCETest, LiveNestedSwitch) {
  3367. const std::string text = R"(OpCapability Shader
  3368. OpMemoryModel Logical GLSL450
  3369. OpEntryPoint Fragment %func "func" %3 %10
  3370. OpExecutionMode %func OriginUpperLeft
  3371. OpName %func "func"
  3372. %void = OpTypeVoid
  3373. %1 = OpTypeFunction %void
  3374. %uint = OpTypeInt 32 0
  3375. %uint_0 = OpConstant %uint 0
  3376. %uint_1 = OpConstant %uint 1
  3377. %_ptr_Output_uint = OpTypePointer Output %uint
  3378. %_ptr_Input_uint = OpTypePointer Input %uint
  3379. %3 = OpVariable %_ptr_Output_uint Output
  3380. %10 = OpVariable %_ptr_Input_uint Input
  3381. %func = OpFunction %void None %1
  3382. %11 = OpLabel
  3383. OpBranch %12
  3384. %12 = OpLabel
  3385. %13 = OpLoad %uint %10
  3386. OpLoopMerge %14 %15 None
  3387. OpBranch %16
  3388. %16 = OpLabel
  3389. OpSelectionMerge %18 None
  3390. OpSwitch %13 %18 0 %17 1 %19
  3391. %17 = OpLabel
  3392. OpStore %3 %uint_1
  3393. OpBranch %19
  3394. %19 = OpLabel
  3395. OpBranch %15
  3396. %15 = OpLabel
  3397. OpBranch %12
  3398. %18 = OpLabel
  3399. OpBranch %14
  3400. %14 = OpLabel
  3401. OpStore %3 %uint_0
  3402. OpReturn
  3403. OpFunctionEnd
  3404. )";
  3405. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  3406. SinglePassRunAndCheck<AggressiveDCEPass>(text, text, false, true);
  3407. }
  3408. TEST_F(AggressiveDCETest, BasicDeleteDeadFunction) {
  3409. // The function Dead should be removed because it is never called.
  3410. const std::vector<const char*> common_code = {
  3411. // clang-format off
  3412. "OpCapability Shader",
  3413. "OpMemoryModel Logical GLSL450",
  3414. "OpEntryPoint Fragment %main \"main\"",
  3415. "OpName %main \"main\"",
  3416. "OpName %Live \"Live\"",
  3417. "%void = OpTypeVoid",
  3418. "%7 = OpTypeFunction %void",
  3419. "%main = OpFunction %void None %7",
  3420. "%15 = OpLabel",
  3421. "%16 = OpFunctionCall %void %Live",
  3422. "%17 = OpFunctionCall %void %Live",
  3423. "OpReturn",
  3424. "OpFunctionEnd",
  3425. "%Live = OpFunction %void None %7",
  3426. "%20 = OpLabel",
  3427. "OpReturn",
  3428. "OpFunctionEnd"
  3429. // clang-format on
  3430. };
  3431. const std::vector<const char*> dead_function = {
  3432. // clang-format off
  3433. "%Dead = OpFunction %void None %7",
  3434. "%19 = OpLabel",
  3435. "OpReturn",
  3436. "OpFunctionEnd",
  3437. // clang-format on
  3438. };
  3439. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  3440. SinglePassRunAndCheck<AggressiveDCEPass>(
  3441. JoinAllInsts(Concat(common_code, dead_function)),
  3442. JoinAllInsts(common_code), /* skip_nop = */ true);
  3443. }
  3444. TEST_F(AggressiveDCETest, BasicKeepLiveFunction) {
  3445. // Everything is reachable from an entry point, so no functions should be
  3446. // deleted.
  3447. const std::vector<const char*> text = {
  3448. // clang-format off
  3449. "OpCapability Shader",
  3450. "OpMemoryModel Logical GLSL450",
  3451. "OpEntryPoint Fragment %main \"main\"",
  3452. "OpName %main \"main\"",
  3453. "OpName %Live1 \"Live1\"",
  3454. "OpName %Live2 \"Live2\"",
  3455. "%void = OpTypeVoid",
  3456. "%7 = OpTypeFunction %void",
  3457. "%main = OpFunction %void None %7",
  3458. "%15 = OpLabel",
  3459. "%16 = OpFunctionCall %void %Live2",
  3460. "%17 = OpFunctionCall %void %Live1",
  3461. "OpReturn",
  3462. "OpFunctionEnd",
  3463. "%Live1 = OpFunction %void None %7",
  3464. "%19 = OpLabel",
  3465. "OpReturn",
  3466. "OpFunctionEnd",
  3467. "%Live2 = OpFunction %void None %7",
  3468. "%20 = OpLabel",
  3469. "OpReturn",
  3470. "OpFunctionEnd"
  3471. // clang-format on
  3472. };
  3473. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  3474. std::string assembly = JoinAllInsts(text);
  3475. auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
  3476. assembly, /* skip_nop = */ true, /* do_validation = */ false);
  3477. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  3478. EXPECT_EQ(assembly, std::get<0>(result));
  3479. }
  3480. TEST_F(AggressiveDCETest, BasicRemoveDecorationsAndNames) {
  3481. // We want to remove the names and decorations associated with results that
  3482. // are removed. This test will check for that.
  3483. const std::string text = R"(
  3484. OpCapability Shader
  3485. OpMemoryModel Logical GLSL450
  3486. OpEntryPoint Vertex %main "main"
  3487. OpName %main "main"
  3488. OpName %Dead "Dead"
  3489. OpName %x "x"
  3490. OpName %y "y"
  3491. OpName %z "z"
  3492. OpDecorate %x RelaxedPrecision
  3493. OpDecorate %y RelaxedPrecision
  3494. OpDecorate %z RelaxedPrecision
  3495. OpDecorate %6 RelaxedPrecision
  3496. OpDecorate %7 RelaxedPrecision
  3497. OpDecorate %8 RelaxedPrecision
  3498. %void = OpTypeVoid
  3499. %10 = OpTypeFunction %void
  3500. %float = OpTypeFloat 32
  3501. %_ptr_Function_float = OpTypePointer Function %float
  3502. %float_1 = OpConstant %float 1
  3503. %main = OpFunction %void None %10
  3504. %14 = OpLabel
  3505. OpReturn
  3506. OpFunctionEnd
  3507. %Dead = OpFunction %void None %10
  3508. %15 = OpLabel
  3509. %x = OpVariable %_ptr_Function_float Function
  3510. %y = OpVariable %_ptr_Function_float Function
  3511. %z = OpVariable %_ptr_Function_float Function
  3512. OpStore %x %float_1
  3513. OpStore %y %float_1
  3514. %6 = OpLoad %float %x
  3515. %7 = OpLoad %float %y
  3516. %8 = OpFAdd %float %6 %7
  3517. OpStore %z %8
  3518. OpReturn
  3519. OpFunctionEnd)";
  3520. const std::string expected_output = R"(OpCapability Shader
  3521. OpMemoryModel Logical GLSL450
  3522. OpEntryPoint Vertex %main "main"
  3523. OpName %main "main"
  3524. %void = OpTypeVoid
  3525. %10 = OpTypeFunction %void
  3526. %main = OpFunction %void None %10
  3527. %14 = OpLabel
  3528. OpReturn
  3529. OpFunctionEnd
  3530. )";
  3531. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  3532. SinglePassRunAndCheck<AggressiveDCEPass>(text, expected_output,
  3533. /* skip_nop = */ true);
  3534. }
  3535. TEST_F(AggressiveDCETest, BasicAllDeadConstants) {
  3536. const std::string text = R"(
  3537. ; CHECK-NOT: OpConstant
  3538. OpCapability Shader
  3539. OpCapability Float64
  3540. %1 = OpExtInstImport "GLSL.std.450"
  3541. OpMemoryModel Logical GLSL450
  3542. OpEntryPoint Vertex %main "main"
  3543. OpName %main "main"
  3544. %void = OpTypeVoid
  3545. %4 = OpTypeFunction %void
  3546. %bool = OpTypeBool
  3547. %true = OpConstantTrue %bool
  3548. %false = OpConstantFalse %bool
  3549. %int = OpTypeInt 32 1
  3550. %9 = OpConstant %int 1
  3551. %uint = OpTypeInt 32 0
  3552. %11 = OpConstant %uint 2
  3553. %float = OpTypeFloat 32
  3554. %13 = OpConstant %float 3.1415
  3555. %double = OpTypeFloat 64
  3556. %15 = OpConstant %double 3.14159265358979
  3557. %main = OpFunction %void None %4
  3558. %16 = OpLabel
  3559. OpReturn
  3560. OpFunctionEnd
  3561. )";
  3562. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  3563. }
  3564. TEST_F(AggressiveDCETest, BasicNoneDeadConstants) {
  3565. const std::vector<const char*> text = {
  3566. // clang-format off
  3567. "OpCapability Shader",
  3568. "OpCapability Float64",
  3569. "%1 = OpExtInstImport \"GLSL.std.450\"",
  3570. "OpMemoryModel Logical GLSL450",
  3571. "OpEntryPoint Vertex %main \"main\" %btv %bfv %iv %uv %fv %dv",
  3572. "OpName %main \"main\"",
  3573. "OpName %btv \"btv\"",
  3574. "OpName %bfv \"bfv\"",
  3575. "OpName %iv \"iv\"",
  3576. "OpName %uv \"uv\"",
  3577. "OpName %fv \"fv\"",
  3578. "OpName %dv \"dv\"",
  3579. "%void = OpTypeVoid",
  3580. "%10 = OpTypeFunction %void",
  3581. "%bool = OpTypeBool",
  3582. "%_ptr_Output_bool = OpTypePointer Output %bool",
  3583. "%true = OpConstantTrue %bool",
  3584. "%false = OpConstantFalse %bool",
  3585. "%int = OpTypeInt 32 1",
  3586. "%_ptr_Output_int = OpTypePointer Output %int",
  3587. "%int_1 = OpConstant %int 1",
  3588. "%uint = OpTypeInt 32 0",
  3589. "%_ptr_Output_uint = OpTypePointer Output %uint",
  3590. "%uint_2 = OpConstant %uint 2",
  3591. "%float = OpTypeFloat 32",
  3592. "%_ptr_Output_float = OpTypePointer Output %float",
  3593. "%float_3_1415 = OpConstant %float 3.1415",
  3594. "%double = OpTypeFloat 64",
  3595. "%_ptr_Output_double = OpTypePointer Output %double",
  3596. "%double_3_14159265358979 = OpConstant %double 3.14159265358979",
  3597. "%btv = OpVariable %_ptr_Output_bool Output",
  3598. "%bfv = OpVariable %_ptr_Output_bool Output",
  3599. "%iv = OpVariable %_ptr_Output_int Output",
  3600. "%uv = OpVariable %_ptr_Output_uint Output",
  3601. "%fv = OpVariable %_ptr_Output_float Output",
  3602. "%dv = OpVariable %_ptr_Output_double Output",
  3603. "%main = OpFunction %void None %10",
  3604. "%27 = OpLabel",
  3605. "OpStore %btv %true",
  3606. "OpStore %bfv %false",
  3607. "OpStore %iv %int_1",
  3608. "OpStore %uv %uint_2",
  3609. "OpStore %fv %float_3_1415",
  3610. "OpStore %dv %double_3_14159265358979",
  3611. "OpReturn",
  3612. "OpFunctionEnd",
  3613. // clang-format on
  3614. };
  3615. // All constants are used, so none of them should be eliminated.
  3616. SinglePassRunAndCheck<AggressiveDCEPass>(
  3617. JoinAllInsts(text), JoinAllInsts(text), /* skip_nop = */ true);
  3618. }
  3619. struct AggressiveEliminateDeadConstantTestCase {
  3620. // Type declarations and constants that should be kept.
  3621. std::vector<std::string> used_consts;
  3622. // Instructions that refer to constants, this is added to create uses for
  3623. // some constants so they won't be treated as dead constants.
  3624. std::vector<std::string> main_insts;
  3625. // Dead constants that should be removed.
  3626. std::vector<std::string> dead_consts;
  3627. // Expectations
  3628. std::vector<std::string> checks;
  3629. };
  3630. // All types that are potentially required in
  3631. // AggressiveEliminateDeadConstantTest.
  3632. const std::vector<std::string> CommonTypes = {
  3633. // clang-format off
  3634. // scalar types
  3635. "%bool = OpTypeBool",
  3636. "%uint = OpTypeInt 32 0",
  3637. "%int = OpTypeInt 32 1",
  3638. "%float = OpTypeFloat 32",
  3639. "%double = OpTypeFloat 64",
  3640. // vector types
  3641. "%v2bool = OpTypeVector %bool 2",
  3642. "%v2uint = OpTypeVector %uint 2",
  3643. "%v2int = OpTypeVector %int 2",
  3644. "%v3int = OpTypeVector %int 3",
  3645. "%v4int = OpTypeVector %int 4",
  3646. "%v2float = OpTypeVector %float 2",
  3647. "%v3float = OpTypeVector %float 3",
  3648. "%v2double = OpTypeVector %double 2",
  3649. // variable pointer types
  3650. "%_pf_bool = OpTypePointer Output %bool",
  3651. "%_pf_uint = OpTypePointer Output %uint",
  3652. "%_pf_int = OpTypePointer Output %int",
  3653. "%_pf_float = OpTypePointer Output %float",
  3654. "%_pf_double = OpTypePointer Output %double",
  3655. "%_pf_v2int = OpTypePointer Output %v2int",
  3656. "%_pf_v3int = OpTypePointer Output %v3int",
  3657. "%_pf_v2float = OpTypePointer Output %v2float",
  3658. "%_pf_v3float = OpTypePointer Output %v3float",
  3659. "%_pf_v2double = OpTypePointer Output %v2double",
  3660. // struct types
  3661. "%inner_struct = OpTypeStruct %bool %int %float %double",
  3662. "%outer_struct = OpTypeStruct %inner_struct %int %double",
  3663. "%flat_struct = OpTypeStruct %bool %int %float %double",
  3664. // clang-format on
  3665. };
  3666. using AggressiveEliminateDeadConstantTest =
  3667. PassTest<::testing::TestWithParam<AggressiveEliminateDeadConstantTestCase>>;
  3668. TEST_P(AggressiveEliminateDeadConstantTest, Custom) {
  3669. auto& tc = GetParam();
  3670. AssemblyBuilder builder;
  3671. builder.AppendTypesConstantsGlobals(CommonTypes)
  3672. .AppendTypesConstantsGlobals(tc.used_consts)
  3673. .AppendInMain(tc.main_insts);
  3674. const std::string expected = builder.GetCode();
  3675. builder.AppendTypesConstantsGlobals(tc.dead_consts);
  3676. builder.PrependPreamble(tc.checks);
  3677. const std::string assembly_with_dead_const = builder.GetCode();
  3678. // Do not enable validation. As the input code is invalid from the base
  3679. // tests (ported from other passes).
  3680. SinglePassRunAndMatch<AggressiveDCEPass>(assembly_with_dead_const, false);
  3681. }
  3682. INSTANTIATE_TEST_SUITE_P(
  3683. ScalarTypeConstants, AggressiveEliminateDeadConstantTest,
  3684. ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
  3685. // clang-format off
  3686. // Scalar type constants, one dead constant and one used constant.
  3687. {
  3688. /* .used_consts = */
  3689. {
  3690. "%used_const_int = OpConstant %int 1",
  3691. },
  3692. /* .main_insts = */
  3693. {
  3694. "%int_var = OpVariable %_pf_int Output",
  3695. "OpStore %int_var %used_const_int",
  3696. },
  3697. /* .dead_consts = */
  3698. {
  3699. "%dead_const_int = OpConstant %int 1",
  3700. },
  3701. /* .checks = */
  3702. {
  3703. "; CHECK: [[const:%\\w+]] = OpConstant %int 1",
  3704. "; CHECK-NOT: OpConstant",
  3705. "; CHECK: OpStore {{%\\w+}} [[const]]",
  3706. },
  3707. },
  3708. {
  3709. /* .used_consts = */
  3710. {
  3711. "%used_const_uint = OpConstant %uint 1",
  3712. },
  3713. /* .main_insts = */
  3714. {
  3715. "%uint_var = OpVariable %_pf_uint Output",
  3716. "OpStore %uint_var %used_const_uint",
  3717. },
  3718. /* .dead_consts = */
  3719. {
  3720. "%dead_const_uint = OpConstant %uint 1",
  3721. },
  3722. /* .checks = */
  3723. {
  3724. "; CHECK: [[const:%\\w+]] = OpConstant %uint 1",
  3725. "; CHECK-NOT: OpConstant",
  3726. "; CHECK: OpStore {{%\\w+}} [[const]]",
  3727. },
  3728. },
  3729. {
  3730. /* .used_consts = */
  3731. {
  3732. "%used_const_float = OpConstant %float 3.1415",
  3733. },
  3734. /* .main_insts = */
  3735. {
  3736. "%float_var = OpVariable %_pf_float Output",
  3737. "OpStore %float_var %used_const_float",
  3738. },
  3739. /* .dead_consts = */
  3740. {
  3741. "%dead_const_float = OpConstant %float 3.1415",
  3742. },
  3743. /* .checks = */
  3744. {
  3745. "; CHECK: [[const:%\\w+]] = OpConstant %float 3.1415",
  3746. "; CHECK-NOT: OpConstant",
  3747. "; CHECK: OpStore {{%\\w+}} [[const]]",
  3748. },
  3749. },
  3750. {
  3751. /* .used_consts = */
  3752. {
  3753. "%used_const_double = OpConstant %double 3.14",
  3754. },
  3755. /* .main_insts = */
  3756. {
  3757. "%double_var = OpVariable %_pf_double Output",
  3758. "OpStore %double_var %used_const_double",
  3759. },
  3760. /* .dead_consts = */
  3761. {
  3762. "%dead_const_double = OpConstant %double 3.14",
  3763. },
  3764. /* .checks = */
  3765. {
  3766. "; CHECK: [[const:%\\w+]] = OpConstant %double 3.14",
  3767. "; CHECK-NOT: OpConstant",
  3768. "; CHECK: OpStore {{%\\w+}} [[const]]",
  3769. },
  3770. },
  3771. // clang-format on
  3772. })));
  3773. INSTANTIATE_TEST_SUITE_P(
  3774. VectorTypeConstants, AggressiveEliminateDeadConstantTest,
  3775. ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
  3776. // clang-format off
  3777. // Tests eliminating dead constant type ivec2. One dead constant vector
  3778. // and one used constant vector, each built from its own group of
  3779. // scalar constants.
  3780. {
  3781. /* .used_consts = */
  3782. {
  3783. "%used_int_x = OpConstant %int 1",
  3784. "%used_int_y = OpConstant %int 2",
  3785. "%used_v2int = OpConstantComposite %v2int %used_int_x %used_int_y",
  3786. },
  3787. /* .main_insts = */
  3788. {
  3789. "%v2int_var = OpVariable %_pf_v2int Output",
  3790. "OpStore %v2int_var %used_v2int",
  3791. },
  3792. /* .dead_consts = */
  3793. {
  3794. "%dead_int_x = OpConstant %int 1",
  3795. "%dead_int_y = OpConstant %int 2",
  3796. "%dead_v2int = OpConstantComposite %v2int %dead_int_x %dead_int_y",
  3797. },
  3798. /* .checks = */
  3799. {
  3800. "; CHECK: [[constx:%\\w+]] = OpConstant %int 1",
  3801. "; CHECK: [[consty:%\\w+]] = OpConstant %int 2",
  3802. "; CHECK: [[const:%\\w+]] = OpConstantComposite %v2int [[constx]] [[consty]]",
  3803. "; CHECK-NOT: OpConstant",
  3804. "; CHECK: OpStore {{%\\w+}} [[const]]",
  3805. },
  3806. },
  3807. // Tests eliminating dead constant ivec3. One dead constant vector and
  3808. // one used constant vector. But both built from a same group of
  3809. // scalar constants.
  3810. {
  3811. /* .used_consts = */
  3812. {
  3813. "%used_int_x = OpConstant %int 1",
  3814. "%used_int_y = OpConstant %int 2",
  3815. "%used_int_z = OpConstant %int 3",
  3816. "%used_v3int = OpConstantComposite %v3int %used_int_x %used_int_y %used_int_z",
  3817. },
  3818. /* .main_insts = */
  3819. {
  3820. "%v3int_var = OpVariable %_pf_v3int Output",
  3821. "OpStore %v3int_var %used_v3int",
  3822. },
  3823. /* .dead_consts = */
  3824. {
  3825. "%dead_v3int = OpConstantComposite %v3int %used_int_x %used_int_y %used_int_z",
  3826. },
  3827. /* .checks = */
  3828. {
  3829. "; CHECK: [[constx:%\\w+]] = OpConstant %int 1",
  3830. "; CHECK: [[consty:%\\w+]] = OpConstant %int 2",
  3831. "; CHECK: [[constz:%\\w+]] = OpConstant %int 3",
  3832. "; CHECK: [[const:%\\w+]] = OpConstantComposite %v3int [[constx]] [[consty]] [[constz]]",
  3833. "; CHECK-NOT: OpConstant",
  3834. "; CHECK: OpStore {{%\\w+}} [[const]]",
  3835. },
  3836. },
  3837. // Tests eliminating dead constant vec2. One dead constant vector and
  3838. // one used constant vector. Each built from its own group of scalar
  3839. // constants.
  3840. {
  3841. /* .used_consts = */
  3842. {
  3843. "%used_float_x = OpConstant %float 3.1415",
  3844. "%used_float_y = OpConstant %float 4.13",
  3845. "%used_v2float = OpConstantComposite %v2float %used_float_x %used_float_y",
  3846. },
  3847. /* .main_insts = */
  3848. {
  3849. "%v2float_var = OpVariable %_pf_v2float Output",
  3850. "OpStore %v2float_var %used_v2float",
  3851. },
  3852. /* .dead_consts = */
  3853. {
  3854. "%dead_float_x = OpConstant %float 3.1415",
  3855. "%dead_float_y = OpConstant %float 4.13",
  3856. "%dead_v2float = OpConstantComposite %v2float %dead_float_x %dead_float_y",
  3857. },
  3858. /* .checks = */
  3859. {
  3860. "; CHECK: [[constx:%\\w+]] = OpConstant %float 3.1415",
  3861. "; CHECK: [[consty:%\\w+]] = OpConstant %float 4.13",
  3862. "; CHECK: [[const:%\\w+]] = OpConstantComposite %v2float [[constx]] [[consty]]",
  3863. "; CHECK-NOT: OpConstant",
  3864. "; CHECK: OpStore {{%\\w+}} [[const]]",
  3865. },
  3866. },
  3867. // Tests eliminating dead constant vec3. One dead constant vector and
  3868. // one used constant vector. Both built from a same group of scalar
  3869. // constants.
  3870. {
  3871. /* .used_consts = */
  3872. {
  3873. "%used_float_x = OpConstant %float 3.1415",
  3874. "%used_float_y = OpConstant %float 4.25",
  3875. "%used_float_z = OpConstant %float 4.75",
  3876. "%used_v3float = OpConstantComposite %v3float %used_float_x %used_float_y %used_float_z",
  3877. },
  3878. /* .main_insts = */
  3879. {
  3880. "%v3float_var = OpVariable %_pf_v3float Output",
  3881. "OpStore %v3float_var %used_v3float",
  3882. },
  3883. /* .dead_consts = */
  3884. {
  3885. "%dead_v3float = OpConstantComposite %v3float %used_float_x %used_float_y %used_float_z",
  3886. },
  3887. /* .checks = */
  3888. {
  3889. "; CHECK: [[constx:%\\w+]] = OpConstant %float 3.1415",
  3890. "; CHECK: [[consty:%\\w+]] = OpConstant %float 4.25",
  3891. "; CHECK: [[constz:%\\w+]] = OpConstant %float 4.75",
  3892. "; CHECK: [[const:%\\w+]] = OpConstantComposite %v3float [[constx]] [[consty]]",
  3893. "; CHECK-NOT: OpConstant",
  3894. "; CHECK: OpStore {{%\\w+}} [[const]]",
  3895. },
  3896. },
  3897. // clang-format on
  3898. })));
  3899. INSTANTIATE_TEST_SUITE_P(
  3900. StructTypeConstants, AggressiveEliminateDeadConstantTest,
  3901. ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
  3902. // clang-format off
  3903. // A plain struct type dead constants. All of its components are dead
  3904. // constants too.
  3905. {
  3906. /* .used_consts = */ {},
  3907. /* .main_insts = */ {},
  3908. /* .dead_consts = */
  3909. {
  3910. "%dead_bool = OpConstantTrue %bool",
  3911. "%dead_int = OpConstant %int 1",
  3912. "%dead_float = OpConstant %float 2.5",
  3913. "%dead_double = OpConstant %double 3.14159265358979",
  3914. "%dead_struct = OpConstantComposite %flat_struct %dead_bool %dead_int %dead_float %dead_double",
  3915. },
  3916. /* .checks = */
  3917. {
  3918. "; CHECK-NOT: OpConstant",
  3919. },
  3920. },
  3921. // A plain struct type dead constants. Some of its components are dead
  3922. // constants while others are not.
  3923. {
  3924. /* .used_consts = */
  3925. {
  3926. "%used_int = OpConstant %int 1",
  3927. "%used_double = OpConstant %double 3.14159265358979",
  3928. },
  3929. /* .main_insts = */
  3930. {
  3931. "%int_var = OpVariable %_pf_int Output",
  3932. "OpStore %int_var %used_int",
  3933. "%double_var = OpVariable %_pf_double Output",
  3934. "OpStore %double_var %used_double",
  3935. },
  3936. /* .dead_consts = */
  3937. {
  3938. "%dead_bool = OpConstantTrue %bool",
  3939. "%dead_float = OpConstant %float 2.5",
  3940. "%dead_struct = OpConstantComposite %flat_struct %dead_bool %used_int %dead_float %used_double",
  3941. },
  3942. /* .checks = */
  3943. {
  3944. "; CHECK: [[int:%\\w+]] = OpConstant %int 1",
  3945. "; CHECK: [[double:%\\w+]] = OpConstant %double 3.14159265358979",
  3946. "; CHECK-NOT: OpConstant",
  3947. "; CHECK: OpStore {{%\\w+}} [[int]]",
  3948. "; CHECK: OpStore {{%\\w+}} [[double]]",
  3949. },
  3950. },
  3951. // A nesting struct type dead constants. All components of both outer
  3952. // and inner structs are dead and should be removed after dead constant
  3953. // elimination.
  3954. {
  3955. /* .used_consts = */ {},
  3956. /* .main_insts = */ {},
  3957. /* .dead_consts = */
  3958. {
  3959. "%dead_bool = OpConstantTrue %bool",
  3960. "%dead_int = OpConstant %int 1",
  3961. "%dead_float = OpConstant %float 2.5",
  3962. "%dead_double = OpConstant %double 3.1415926535",
  3963. "%dead_inner_struct = OpConstantComposite %inner_struct %dead_bool %dead_int %dead_float %dead_double",
  3964. "%dead_int2 = OpConstant %int 2",
  3965. "%dead_double2 = OpConstant %double 1.428571428514",
  3966. "%dead_outer_struct = OpConstantComposite %outer_struct %dead_inner_struct %dead_int2 %dead_double2",
  3967. },
  3968. /* .checks = */
  3969. {
  3970. "; CHECK-NOT: OpConstant",
  3971. },
  3972. },
  3973. // A nesting struct type dead constants. Some of its components are
  3974. // dead constants while others are not.
  3975. {
  3976. /* .used_consts = */
  3977. {
  3978. "%used_int = OpConstant %int 1",
  3979. "%used_double = OpConstant %double 3.14159265358979",
  3980. },
  3981. /* .main_insts = */
  3982. {
  3983. "%int_var = OpVariable %_pf_int Output",
  3984. "OpStore %int_var %used_int",
  3985. "%double_var = OpVariable %_pf_double Output",
  3986. "OpStore %double_var %used_double",
  3987. },
  3988. /* .dead_consts = */
  3989. {
  3990. "%dead_bool = OpConstantTrue %bool",
  3991. "%dead_float = OpConstant %float 2.5",
  3992. "%dead_inner_struct = OpConstantComposite %inner_struct %dead_bool %used_int %dead_float %used_double",
  3993. "%dead_int = OpConstant %int 2",
  3994. "%dead_outer_struct = OpConstantComposite %outer_struct %dead_inner_struct %dead_int %used_double",
  3995. },
  3996. /* .checks = */
  3997. {
  3998. "; CHECK: [[int:%\\w+]] = OpConstant %int 1",
  3999. "; CHECK: [[double:%\\w+]] = OpConstant %double 3.14159265358979",
  4000. "; CHECK-NOT: OpConstant",
  4001. "; CHECK: OpStore {{%\\w+}} [[int]]",
  4002. "; CHECK: OpStore {{%\\w+}} [[double]]",
  4003. },
  4004. },
  4005. // A nesting struct case. The inner struct is used while the outer struct is not
  4006. {
  4007. /* .used_const = */
  4008. {
  4009. "%used_bool = OpConstantTrue %bool",
  4010. "%used_int = OpConstant %int 1",
  4011. "%used_float = OpConstant %float 1.23",
  4012. "%used_double = OpConstant %double 1.2345678901234",
  4013. "%used_inner_struct = OpConstantComposite %inner_struct %used_bool %used_int %used_float %used_double",
  4014. },
  4015. /* .main_insts = */
  4016. {
  4017. "%bool_var = OpVariable %_pf_bool Output",
  4018. "%bool_from_inner_struct = OpCompositeExtract %bool %used_inner_struct 0",
  4019. "OpStore %bool_var %bool_from_inner_struct",
  4020. },
  4021. /* .dead_consts = */
  4022. {
  4023. "%dead_int = OpConstant %int 2",
  4024. "%dead_outer_struct = OpConstantComposite %outer_struct %used_inner_struct %dead_int %used_double"
  4025. },
  4026. /* .checks = */
  4027. {
  4028. "; CHECK: [[bool:%\\w+]] = OpConstantTrue",
  4029. "; CHECK: [[int:%\\w+]] = OpConstant %int 1",
  4030. "; CHECK: [[float:%\\w+]] = OpConstant %float 1.23",
  4031. "; CHECK: [[double:%\\w+]] = OpConstant %double 1.2345678901234",
  4032. "; CHECK: [[struct:%\\w+]] = OpConstantComposite %inner_struct [[bool]] [[int]] [[float]] [[double]]",
  4033. "; CHECK-NOT: OpConstant",
  4034. "; CHECK: OpCompositeExtract %bool [[struct]]",
  4035. }
  4036. },
  4037. // A nesting struct case. The outer struct is used, so the inner struct should not
  4038. // be removed even though it is not used anywhere.
  4039. {
  4040. /* .used_const = */
  4041. {
  4042. "%used_bool = OpConstantTrue %bool",
  4043. "%used_int = OpConstant %int 1",
  4044. "%used_float = OpConstant %float 1.23",
  4045. "%used_double = OpConstant %double 1.2345678901234",
  4046. "%used_inner_struct = OpConstantComposite %inner_struct %used_bool %used_int %used_float %used_double",
  4047. "%used_outer_struct = OpConstantComposite %outer_struct %used_inner_struct %used_int %used_double"
  4048. },
  4049. /* .main_insts = */
  4050. {
  4051. "%int_var = OpVariable %_pf_int Output",
  4052. "%int_from_outer_struct = OpCompositeExtract %int %used_outer_struct 1",
  4053. "OpStore %int_var %int_from_outer_struct",
  4054. },
  4055. /* .dead_consts = */ {},
  4056. /* .checks = */
  4057. {
  4058. "; CHECK: [[bool:%\\w+]] = OpConstantTrue %bool",
  4059. "; CHECK: [[int:%\\w+]] = OpConstant %int 1",
  4060. "; CHECK: [[float:%\\w+]] = OpConstant %float 1.23",
  4061. "; CHECK: [[double:%\\w+]] = OpConstant %double 1.2345678901234",
  4062. "; CHECK: [[inner_struct:%\\w+]] = OpConstantComposite %inner_struct %used_bool %used_int %used_float %used_double",
  4063. "; CHECK: [[outer_struct:%\\w+]] = OpConstantComposite %outer_struct %used_inner_struct %used_int %used_double",
  4064. "; CHECK: OpCompositeExtract %int [[outer_struct]]",
  4065. },
  4066. },
  4067. // clang-format on
  4068. })));
  4069. INSTANTIATE_TEST_SUITE_P(
  4070. ScalarTypeSpecConstants, AggressiveEliminateDeadConstantTest,
  4071. ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
  4072. // clang-format off
  4073. // All scalar type spec constants.
  4074. {
  4075. /* .used_consts = */
  4076. {
  4077. "%used_bool = OpSpecConstantTrue %bool",
  4078. "%used_uint = OpSpecConstant %uint 2",
  4079. "%used_int = OpSpecConstant %int 2",
  4080. "%used_float = OpSpecConstant %float 2.5",
  4081. "%used_double = OpSpecConstant %double 1.428571428514",
  4082. },
  4083. /* .main_insts = */
  4084. {
  4085. "%bool_var = OpVariable %_pf_bool Output",
  4086. "%uint_var = OpVariable %_pf_uint Output",
  4087. "%int_var = OpVariable %_pf_int Output",
  4088. "%float_var = OpVariable %_pf_float Output",
  4089. "%double_var = OpVariable %_pf_double Output",
  4090. "OpStore %bool_var %used_bool",
  4091. "OpStore %uint_var %used_uint",
  4092. "OpStore %int_var %used_int",
  4093. "OpStore %float_var %used_float",
  4094. "OpStore %double_var %used_double",
  4095. },
  4096. /* .dead_consts = */
  4097. {
  4098. "%dead_bool = OpSpecConstantTrue %bool",
  4099. "%dead_uint = OpSpecConstant %uint 2",
  4100. "%dead_int = OpSpecConstant %int 2",
  4101. "%dead_float = OpSpecConstant %float 2.5",
  4102. "%dead_double = OpSpecConstant %double 1.428571428514",
  4103. },
  4104. /* .checks = */
  4105. {
  4106. "; CHECK: [[bool:%\\w+]] = OpSpecConstantTrue %bool",
  4107. "; CHECK: [[uint:%\\w+]] = OpSpecConstant %uint 2",
  4108. "; CHECK: [[int:%\\w+]] = OpSpecConstant %int 2",
  4109. "; CHECK: [[float:%\\w+]] = OpSpecConstant %float 2.5",
  4110. "; CHECK: [[double:%\\w+]] = OpSpecConstant %double 1.428571428514",
  4111. "; CHECK-NOT: OpSpecConstant",
  4112. "; CHECK: OpStore {{%\\w+}} [[bool]]",
  4113. "; CHECK: OpStore {{%\\w+}} [[uint]]",
  4114. "; CHECK: OpStore {{%\\w+}} [[int]]",
  4115. "; CHECK: OpStore {{%\\w+}} [[float]]",
  4116. "; CHECK: OpStore {{%\\w+}} [[double]]",
  4117. },
  4118. },
  4119. // clang-format on
  4120. })));
  4121. INSTANTIATE_TEST_SUITE_P(
  4122. VectorTypeSpecConstants, AggressiveEliminateDeadConstantTest,
  4123. ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
  4124. // clang-format off
  4125. // Bool vector type spec constants. One vector has all component dead,
  4126. // another vector has one dead boolean and one used boolean.
  4127. {
  4128. /* .used_consts = */
  4129. {
  4130. "%used_bool = OpSpecConstantTrue %bool",
  4131. },
  4132. /* .main_insts = */
  4133. {
  4134. "%bool_var = OpVariable %_pf_bool Output",
  4135. "OpStore %bool_var %used_bool",
  4136. },
  4137. /* .dead_consts = */
  4138. {
  4139. "%dead_bool = OpSpecConstantFalse %bool",
  4140. "%dead_bool_vec1 = OpSpecConstantComposite %v2bool %dead_bool %dead_bool",
  4141. "%dead_bool_vec2 = OpSpecConstantComposite %v2bool %dead_bool %used_bool",
  4142. },
  4143. /* .checks = */
  4144. {
  4145. "; CHECK: [[bool:%\\w+]] = OpSpecConstantTrue %bool",
  4146. "; CHECK-NOT: OpSpecConstant",
  4147. "; CHECK: OpStore {{%\\w+}} [[bool]]",
  4148. },
  4149. },
  4150. // Uint vector type spec constants. One vector has all component dead,
  4151. // another vector has one dead unsigned integer and one used unsigned
  4152. // integer.
  4153. {
  4154. /* .used_consts = */
  4155. {
  4156. "%used_uint = OpSpecConstant %uint 3",
  4157. },
  4158. /* .main_insts = */
  4159. {
  4160. "%uint_var = OpVariable %_pf_uint Output",
  4161. "OpStore %uint_var %used_uint",
  4162. },
  4163. /* .dead_consts = */
  4164. {
  4165. "%dead_uint = OpSpecConstant %uint 1",
  4166. "%dead_uint_vec1 = OpSpecConstantComposite %v2uint %dead_uint %dead_uint",
  4167. "%dead_uint_vec2 = OpSpecConstantComposite %v2uint %dead_uint %used_uint",
  4168. },
  4169. /* .checks = */
  4170. {
  4171. "; CHECK: [[uint:%\\w+]] = OpSpecConstant %uint 3",
  4172. "; CHECK-NOT: OpSpecConstant",
  4173. "; CHECK: OpStore {{%\\w+}} [[uint]]",
  4174. },
  4175. },
  4176. // Int vector type spec constants. One vector has all component dead,
  4177. // another vector has one dead integer and one used integer.
  4178. {
  4179. /* .used_consts = */
  4180. {
  4181. "%used_int = OpSpecConstant %int 3",
  4182. },
  4183. /* .main_insts = */
  4184. {
  4185. "%int_var = OpVariable %_pf_int Output",
  4186. "OpStore %int_var %used_int",
  4187. },
  4188. /* .dead_consts = */
  4189. {
  4190. "%dead_int = OpSpecConstant %int 1",
  4191. "%dead_int_vec1 = OpSpecConstantComposite %v2int %dead_int %dead_int",
  4192. "%dead_int_vec2 = OpSpecConstantComposite %v2int %dead_int %used_int",
  4193. },
  4194. /* .checks = */
  4195. {
  4196. "; CHECK: [[int:%\\w+]] = OpSpecConstant %int 3",
  4197. "; CHECK-NOT: OpSpecConstant",
  4198. "; CHECK: OpStore {{%\\w+}} [[int]]",
  4199. },
  4200. },
  4201. // Int vector type spec constants built with both spec constants and
  4202. // front-end constants.
  4203. {
  4204. /* .used_consts = */
  4205. {
  4206. "%used_spec_int = OpSpecConstant %int 3",
  4207. "%used_front_end_int = OpConstant %int 3",
  4208. },
  4209. /* .main_insts = */
  4210. {
  4211. "%int_var1 = OpVariable %_pf_int Output",
  4212. "OpStore %int_var1 %used_spec_int",
  4213. "%int_var2 = OpVariable %_pf_int Output",
  4214. "OpStore %int_var2 %used_front_end_int",
  4215. },
  4216. /* .dead_consts = */
  4217. {
  4218. "%dead_spec_int = OpSpecConstant %int 1",
  4219. "%dead_front_end_int = OpConstant %int 1",
  4220. // Dead front-end and dead spec constants
  4221. "%dead_int_vec1 = OpSpecConstantComposite %v2int %dead_spec_int %dead_front_end_int",
  4222. // Used front-end and dead spec constants
  4223. "%dead_int_vec2 = OpSpecConstantComposite %v2int %dead_spec_int %used_front_end_int",
  4224. // Dead front-end and used spec constants
  4225. "%dead_int_vec3 = OpSpecConstantComposite %v2int %dead_front_end_int %used_spec_int",
  4226. },
  4227. /* .checks = */
  4228. {
  4229. "; CHECK: [[int1:%\\w+]] = OpSpecConstant %int 3",
  4230. "; CHECK: [[int2:%\\w+]] = OpConstant %int 3",
  4231. "; CHECK-NOT: OpSpecConstant",
  4232. "; CHECK-NOT: OpConstant",
  4233. "; CHECK: OpStore {{%\\w+}} [[int1]]",
  4234. "; CHECK: OpStore {{%\\w+}} [[int2]]",
  4235. },
  4236. },
  4237. // clang-format on
  4238. })));
  4239. INSTANTIATE_TEST_SUITE_P(
  4240. SpecConstantOp, AggressiveEliminateDeadConstantTest,
  4241. ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
  4242. // clang-format off
  4243. // Cast operations: uint <-> int <-> bool
  4244. {
  4245. /* .used_consts = */ {},
  4246. /* .main_insts = */ {},
  4247. /* .dead_consts = */
  4248. {
  4249. // Assistant constants, only used in dead spec constant
  4250. // operations.
  4251. "%signed_zero = OpConstant %int 0",
  4252. "%signed_zero_vec = OpConstantComposite %v2int %signed_zero %signed_zero",
  4253. "%unsigned_zero = OpConstant %uint 0",
  4254. "%unsigned_zero_vec = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero",
  4255. "%signed_one = OpConstant %int 1",
  4256. "%signed_one_vec = OpConstantComposite %v2int %signed_one %signed_one",
  4257. "%unsigned_one = OpConstant %uint 1",
  4258. "%unsigned_one_vec = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
  4259. // Spec constants that support casting to each other.
  4260. "%dead_bool = OpSpecConstantTrue %bool",
  4261. "%dead_uint = OpSpecConstant %uint 1",
  4262. "%dead_int = OpSpecConstant %int 2",
  4263. "%dead_bool_vec = OpSpecConstantComposite %v2bool %dead_bool %dead_bool",
  4264. "%dead_uint_vec = OpSpecConstantComposite %v2uint %dead_uint %dead_uint",
  4265. "%dead_int_vec = OpSpecConstantComposite %v2int %dead_int %dead_int",
  4266. // Scalar cast to boolean spec constant.
  4267. "%int_to_bool = OpSpecConstantOp %bool INotEqual %dead_int %signed_zero",
  4268. "%uint_to_bool = OpSpecConstantOp %bool INotEqual %dead_uint %unsigned_zero",
  4269. // Vector cast to boolean spec constant.
  4270. "%int_to_bool_vec = OpSpecConstantOp %v2bool INotEqual %dead_int_vec %signed_zero_vec",
  4271. "%uint_to_bool_vec = OpSpecConstantOp %v2bool INotEqual %dead_uint_vec %unsigned_zero_vec",
  4272. // Scalar cast to int spec constant.
  4273. "%bool_to_int = OpSpecConstantOp %int Select %dead_bool %signed_one %signed_zero",
  4274. "%uint_to_int = OpSpecConstantOp %uint IAdd %dead_uint %unsigned_zero",
  4275. // Vector cast to int spec constant.
  4276. "%bool_to_int_vec = OpSpecConstantOp %v2int Select %dead_bool_vec %signed_one_vec %signed_zero_vec",
  4277. "%uint_to_int_vec = OpSpecConstantOp %v2uint IAdd %dead_uint_vec %unsigned_zero_vec",
  4278. // Scalar cast to uint spec constant.
  4279. "%bool_to_uint = OpSpecConstantOp %uint Select %dead_bool %unsigned_one %unsigned_zero",
  4280. "%int_to_uint_vec = OpSpecConstantOp %uint IAdd %dead_int %signed_zero",
  4281. // Vector cast to uint spec constant.
  4282. "%bool_to_uint_vec = OpSpecConstantOp %v2uint Select %dead_bool_vec %unsigned_one_vec %unsigned_zero_vec",
  4283. "%int_to_uint = OpSpecConstantOp %v2uint IAdd %dead_int_vec %signed_zero_vec",
  4284. },
  4285. /* .checks = */
  4286. {
  4287. "; CHECK-NOT: OpConstant",
  4288. "; CHECK-NOT: OpSpecConstant",
  4289. },
  4290. },
  4291. // Add, sub, mul, div, rem.
  4292. {
  4293. /* .used_consts = */ {},
  4294. /* .main_insts = */ {},
  4295. /* .dead_consts = */
  4296. {
  4297. "%dead_spec_int_a = OpSpecConstant %int 1",
  4298. "%dead_spec_int_a_vec = OpSpecConstantComposite %v2int %dead_spec_int_a %dead_spec_int_a",
  4299. "%dead_spec_int_b = OpSpecConstant %int 2",
  4300. "%dead_spec_int_b_vec = OpSpecConstantComposite %v2int %dead_spec_int_b %dead_spec_int_b",
  4301. "%dead_const_int_c = OpConstant %int 3",
  4302. "%dead_const_int_c_vec = OpConstantComposite %v2int %dead_const_int_c %dead_const_int_c",
  4303. // Add
  4304. "%add_a_b = OpSpecConstantOp %int IAdd %dead_spec_int_a %dead_spec_int_b",
  4305. "%add_a_b_vec = OpSpecConstantOp %v2int IAdd %dead_spec_int_a_vec %dead_spec_int_b_vec",
  4306. // Sub
  4307. "%sub_a_b = OpSpecConstantOp %int ISub %dead_spec_int_a %dead_spec_int_b",
  4308. "%sub_a_b_vec = OpSpecConstantOp %v2int ISub %dead_spec_int_a_vec %dead_spec_int_b_vec",
  4309. // Mul
  4310. "%mul_a_b = OpSpecConstantOp %int IMul %dead_spec_int_a %dead_spec_int_b",
  4311. "%mul_a_b_vec = OpSpecConstantOp %v2int IMul %dead_spec_int_a_vec %dead_spec_int_b_vec",
  4312. // Div
  4313. "%div_a_b = OpSpecConstantOp %int SDiv %dead_spec_int_a %dead_spec_int_b",
  4314. "%div_a_b_vec = OpSpecConstantOp %v2int SDiv %dead_spec_int_a_vec %dead_spec_int_b_vec",
  4315. // Bitwise Xor
  4316. "%xor_a_b = OpSpecConstantOp %int BitwiseXor %dead_spec_int_a %dead_spec_int_b",
  4317. "%xor_a_b_vec = OpSpecConstantOp %v2int BitwiseXor %dead_spec_int_a_vec %dead_spec_int_b_vec",
  4318. // Scalar Comparison
  4319. "%less_a_b = OpSpecConstantOp %bool SLessThan %dead_spec_int_a %dead_spec_int_b",
  4320. },
  4321. /* .checks = */
  4322. {
  4323. "; CHECK-NOT: OpConstant",
  4324. "; CHECK-NOT: OpSpecConstant",
  4325. },
  4326. },
  4327. // Vectors without used swizzles should be removed.
  4328. {
  4329. /* .used_consts = */
  4330. {
  4331. "%used_int = OpConstant %int 3",
  4332. },
  4333. /* .main_insts = */
  4334. {
  4335. "%int_var = OpVariable %_pf_int Output",
  4336. "OpStore %int_var %used_int",
  4337. },
  4338. /* .dead_consts = */
  4339. {
  4340. "%dead_int = OpConstant %int 3",
  4341. "%dead_spec_int_a = OpSpecConstant %int 1",
  4342. "%vec_a = OpSpecConstantComposite %v4int %dead_spec_int_a %dead_spec_int_a %dead_int %dead_int",
  4343. "%dead_spec_int_b = OpSpecConstant %int 2",
  4344. "%vec_b = OpSpecConstantComposite %v4int %dead_spec_int_b %dead_spec_int_b %used_int %used_int",
  4345. // Extract scalar
  4346. "%a_x = OpSpecConstantOp %int CompositeExtract %vec_a 0",
  4347. "%b_x = OpSpecConstantOp %int CompositeExtract %vec_b 0",
  4348. // Extract vector
  4349. "%a_xy = OpSpecConstantOp %v2int VectorShuffle %vec_a %vec_a 0 1",
  4350. "%b_xy = OpSpecConstantOp %v2int VectorShuffle %vec_b %vec_b 0 1",
  4351. },
  4352. /* .checks = */
  4353. {
  4354. "; CHECK: [[int:%\\w+]] = OpConstant %int 3",
  4355. "; CHECK-NOT: OpConstant",
  4356. "; CHECK-NOT: OpSpecConstant",
  4357. "; CHECK: OpStore {{%\\w+}} [[int]]",
  4358. },
  4359. },
  4360. // Vectors with used swizzles should not be removed.
  4361. {
  4362. /* .used_consts = */
  4363. {
  4364. "%used_int = OpConstant %int 3",
  4365. "%used_spec_int_a = OpSpecConstant %int 1",
  4366. "%used_spec_int_b = OpSpecConstant %int 2",
  4367. // Create vectors
  4368. "%vec_a = OpSpecConstantComposite %v4int %used_spec_int_a %used_spec_int_a %used_int %used_int",
  4369. "%vec_b = OpSpecConstantComposite %v4int %used_spec_int_b %used_spec_int_b %used_int %used_int",
  4370. // Extract vector
  4371. "%a_xy = OpSpecConstantOp %v2int VectorShuffle %vec_a %vec_a 0 1",
  4372. "%b_xy = OpSpecConstantOp %v2int VectorShuffle %vec_b %vec_b 0 1",
  4373. },
  4374. /* .main_insts = */
  4375. {
  4376. "%v2int_var_a = OpVariable %_pf_v2int Output",
  4377. "%v2int_var_b = OpVariable %_pf_v2int Output",
  4378. "OpStore %v2int_var_a %a_xy",
  4379. "OpStore %v2int_var_b %b_xy",
  4380. },
  4381. /* .dead_consts = */ {},
  4382. /* .checks = */
  4383. {
  4384. "; CHECK: [[int:%\\w+]] = OpConstant %int 3",
  4385. "; CHECK: [[a:%\\w+]] = OpSpecConstant %int 1",
  4386. "; CHECK: [[b:%\\w+]] = OpSpecConstant %int 2",
  4387. "; CHECK: [[veca:%\\w+]] = OpSpecConstantComposite %v4int [[a]] [[a]] [[int]] [[int]]",
  4388. "; CHECK: [[vecb:%\\w+]] = OpSpecConstantComposite %v4int [[b]] [[b]] [[int]] [[int]]",
  4389. "; CHECK: [[exa:%\\w+]] = OpSpecConstantOp %v2int VectorShuffle [[veca]] [[veca]] 0 1",
  4390. "; CHECK: [[exb:%\\w+]] = OpSpecConstantOp %v2int VectorShuffle [[vecb]] [[vecb]] 0 1",
  4391. "; CHECK-NOT: OpConstant",
  4392. "; CHECK-NOT: OpSpecConstant",
  4393. "; CHECK: OpStore {{%\\w+}} [[exa]]",
  4394. "; CHECK: OpStore {{%\\w+}} [[exb]]",
  4395. },
  4396. },
  4397. // clang-format on
  4398. })));
  4399. INSTANTIATE_TEST_SUITE_P(
  4400. LongDefUseChain, AggressiveEliminateDeadConstantTest,
  4401. ::testing::ValuesIn(std::vector<AggressiveEliminateDeadConstantTestCase>({
  4402. // clang-format off
  4403. // Long Def-Use chain with binary operations.
  4404. {
  4405. /* .used_consts = */
  4406. {
  4407. "%array_size = OpConstant %int 4",
  4408. "%type_arr_int_4 = OpTypeArray %int %array_size",
  4409. "%used_int_0 = OpConstant %int 100",
  4410. "%used_int_1 = OpConstant %int 1",
  4411. "%used_int_2 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_1",
  4412. "%used_int_3 = OpSpecConstantOp %int ISub %used_int_0 %used_int_2",
  4413. "%used_int_4 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_3",
  4414. "%used_int_5 = OpSpecConstantOp %int ISub %used_int_0 %used_int_4",
  4415. "%used_int_6 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_5",
  4416. "%used_int_7 = OpSpecConstantOp %int ISub %used_int_0 %used_int_6",
  4417. "%used_int_8 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_7",
  4418. "%used_int_9 = OpSpecConstantOp %int ISub %used_int_0 %used_int_8",
  4419. "%used_int_10 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_9",
  4420. "%used_int_11 = OpSpecConstantOp %int ISub %used_int_0 %used_int_10",
  4421. "%used_int_12 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_11",
  4422. "%used_int_13 = OpSpecConstantOp %int ISub %used_int_0 %used_int_12",
  4423. "%used_int_14 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_13",
  4424. "%used_int_15 = OpSpecConstantOp %int ISub %used_int_0 %used_int_14",
  4425. "%used_int_16 = OpSpecConstantOp %int ISub %used_int_0 %used_int_15",
  4426. "%used_int_17 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_16",
  4427. "%used_int_18 = OpSpecConstantOp %int ISub %used_int_0 %used_int_17",
  4428. "%used_int_19 = OpSpecConstantOp %int IAdd %used_int_0 %used_int_18",
  4429. "%used_int_20 = OpSpecConstantOp %int ISub %used_int_0 %used_int_19",
  4430. "%used_vec_a = OpSpecConstantComposite %v2int %used_int_18 %used_int_19",
  4431. "%used_vec_b = OpSpecConstantOp %v2int IMul %used_vec_a %used_vec_a",
  4432. "%used_int_21 = OpSpecConstantOp %int CompositeExtract %used_vec_b 0",
  4433. "%used_array = OpConstantComposite %type_arr_int_4 %used_int_20 %used_int_20 %used_int_21 %used_int_21",
  4434. },
  4435. /* .main_insts = */
  4436. {
  4437. "%int_var = OpVariable %_pf_int Output",
  4438. "%used_array_2 = OpCompositeExtract %int %used_array 2",
  4439. "OpStore %int_var %used_array_2",
  4440. },
  4441. /* .dead_consts = */
  4442. {
  4443. "%dead_int_1 = OpConstant %int 2",
  4444. "%dead_int_2 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_1",
  4445. "%dead_int_3 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_2",
  4446. "%dead_int_4 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_3",
  4447. "%dead_int_5 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_4",
  4448. "%dead_int_6 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_5",
  4449. "%dead_int_7 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_6",
  4450. "%dead_int_8 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_7",
  4451. "%dead_int_9 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_8",
  4452. "%dead_int_10 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_9",
  4453. "%dead_int_11 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_10",
  4454. "%dead_int_12 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_11",
  4455. "%dead_int_13 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_12",
  4456. "%dead_int_14 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_13",
  4457. "%dead_int_15 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_14",
  4458. "%dead_int_16 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_15",
  4459. "%dead_int_17 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_16",
  4460. "%dead_int_18 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_17",
  4461. "%dead_int_19 = OpSpecConstantOp %int IAdd %used_int_0 %dead_int_18",
  4462. "%dead_int_20 = OpSpecConstantOp %int ISub %used_int_0 %dead_int_19",
  4463. "%dead_vec_a = OpSpecConstantComposite %v2int %dead_int_18 %dead_int_19",
  4464. "%dead_vec_b = OpSpecConstantOp %v2int IMul %dead_vec_a %dead_vec_a",
  4465. "%dead_int_21 = OpSpecConstantOp %int CompositeExtract %dead_vec_b 0",
  4466. "%dead_array = OpConstantComposite %type_arr_int_4 %dead_int_20 %used_int_20 %dead_int_19 %used_int_19",
  4467. },
  4468. /* .checks = */
  4469. {
  4470. "; CHECK: OpConstant %int 4",
  4471. "; CHECK: [[array:%\\w+]] = OpConstantComposite %type_arr_int_4 %used_int_20 %used_int_20 %used_int_21 %used_int_21",
  4472. "; CHECK-NOT: OpConstant",
  4473. "; CHECK-NOT: OpSpecConstant",
  4474. "; CHECK: OpStore {{%\\w+}} [[array]]",
  4475. },
  4476. },
  4477. // Long Def-Use chain with swizzle
  4478. // clang-format on
  4479. })));
  4480. TEST_F(AggressiveDCETest, DeadDecorationGroup) {
  4481. // The decoration group should be eliminated because the target of group
  4482. // decorate is dead.
  4483. const std::string text = R"(
  4484. ; CHECK-NOT: OpDecorat
  4485. ; CHECK-NOT: OpGroupDecorate
  4486. OpCapability Shader
  4487. OpMemoryModel Logical GLSL450
  4488. OpEntryPoint Fragment %main "main"
  4489. OpExecutionMode %main OriginUpperLeft
  4490. OpDecorate %1 Restrict
  4491. OpDecorate %1 Aliased
  4492. %1 = OpDecorationGroup
  4493. OpGroupDecorate %1 %var
  4494. %void = OpTypeVoid
  4495. %func = OpTypeFunction %void
  4496. %uint = OpTypeInt 32 0
  4497. %uint_ptr = OpTypePointer Function %uint
  4498. %main = OpFunction %void None %func
  4499. %2 = OpLabel
  4500. %var = OpVariable %uint_ptr Function
  4501. OpReturn
  4502. OpFunctionEnd
  4503. )";
  4504. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  4505. }
  4506. TEST_F(AggressiveDCETest, DeadDecorationGroupAndValidDecorationMgr) {
  4507. // The decoration group should be eliminated because the target of group
  4508. // decorate is dead.
  4509. const std::string text = R"(
  4510. OpCapability Shader
  4511. OpMemoryModel Logical GLSL450
  4512. OpEntryPoint Fragment %main "main"
  4513. OpExecutionMode %main OriginUpperLeft
  4514. OpDecorate %1 Restrict
  4515. OpDecorate %1 Aliased
  4516. %1 = OpDecorationGroup
  4517. OpGroupDecorate %1 %var
  4518. %void = OpTypeVoid
  4519. %func = OpTypeFunction %void
  4520. %uint = OpTypeInt 32 0
  4521. %uint_ptr = OpTypePointer Function %uint
  4522. %main = OpFunction %void None %func
  4523. %2 = OpLabel
  4524. %var = OpVariable %uint_ptr Function
  4525. OpReturn
  4526. OpFunctionEnd
  4527. )";
  4528. auto pass = MakeUnique<AggressiveDCEPass>();
  4529. auto consumer = [](spv_message_level_t, const char*, const spv_position_t&,
  4530. const char* message) {
  4531. std::cerr << message << std::endl;
  4532. };
  4533. auto context = BuildModule(SPV_ENV_UNIVERSAL_1_1, consumer, text);
  4534. // Build the decoration manager before the pass.
  4535. context->get_decoration_mgr();
  4536. const auto status = pass->Run(context.get());
  4537. EXPECT_EQ(status, Pass::Status::SuccessWithChange);
  4538. }
  4539. TEST_F(AggressiveDCETest, ParitallyDeadDecorationGroup) {
  4540. const std::string text = R"(
  4541. ; CHECK: OpDecorate [[grp:%\w+]] Restrict
  4542. ; CHECK: [[grp]] = OpDecorationGroup
  4543. ; CHECK: OpGroupDecorate [[grp]] [[output:%\w+]]
  4544. ; CHECK: [[output]] = OpVariable {{%\w+}} Output
  4545. ; CHECK-NOT: OpVariable {{%\w+}} Function
  4546. OpCapability Shader
  4547. OpMemoryModel Logical GLSL450
  4548. OpEntryPoint Fragment %main "main" %output
  4549. OpExecutionMode %main OriginUpperLeft
  4550. OpDecorate %1 Restrict
  4551. %1 = OpDecorationGroup
  4552. OpGroupDecorate %1 %var %output
  4553. %void = OpTypeVoid
  4554. %func = OpTypeFunction %void
  4555. %uint = OpTypeInt 32 0
  4556. %uint_ptr_Function = OpTypePointer Function %uint
  4557. %uint_ptr_Output = OpTypePointer Output %uint
  4558. %uint_0 = OpConstant %uint 0
  4559. %output = OpVariable %uint_ptr_Output Output
  4560. %main = OpFunction %void None %func
  4561. %2 = OpLabel
  4562. %var = OpVariable %uint_ptr_Function Function
  4563. OpStore %output %uint_0
  4564. OpReturn
  4565. OpFunctionEnd
  4566. )";
  4567. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  4568. }
  4569. TEST_F(AggressiveDCETest, ParitallyDeadDecorationGroupDifferentGroupDecorate) {
  4570. const std::string text = R"(
  4571. ; CHECK: OpDecorate [[grp:%\w+]] Restrict
  4572. ; CHECK: [[grp]] = OpDecorationGroup
  4573. ; CHECK: OpGroupDecorate [[grp]] [[output:%\w+]]
  4574. ; CHECK-NOT: OpGroupDecorate
  4575. ; CHECK: [[output]] = OpVariable {{%\w+}} Output
  4576. ; CHECK-NOT: OpVariable {{%\w+}} Function
  4577. OpCapability Shader
  4578. OpMemoryModel Logical GLSL450
  4579. OpEntryPoint Fragment %main "main" %output
  4580. OpExecutionMode %main OriginUpperLeft
  4581. OpDecorate %1 Restrict
  4582. %1 = OpDecorationGroup
  4583. OpGroupDecorate %1 %output
  4584. OpGroupDecorate %1 %var
  4585. %void = OpTypeVoid
  4586. %func = OpTypeFunction %void
  4587. %uint = OpTypeInt 32 0
  4588. %uint_ptr_Function = OpTypePointer Function %uint
  4589. %uint_ptr_Output = OpTypePointer Output %uint
  4590. %uint_0 = OpConstant %uint 0
  4591. %output = OpVariable %uint_ptr_Output Output
  4592. %main = OpFunction %void None %func
  4593. %2 = OpLabel
  4594. %var = OpVariable %uint_ptr_Function Function
  4595. OpStore %output %uint_0
  4596. OpReturn
  4597. OpFunctionEnd
  4598. )";
  4599. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  4600. }
  4601. TEST_F(AggressiveDCETest, DeadGroupMemberDecorate) {
  4602. const std::string text = R"(
  4603. ; CHECK-NOT: OpDec
  4604. ; CHECK-NOT: OpGroup
  4605. OpCapability Shader
  4606. OpMemoryModel Logical GLSL450
  4607. OpEntryPoint Fragment %main "main"
  4608. OpExecutionMode %main OriginUpperLeft
  4609. OpDecorate %1 Offset 0
  4610. OpDecorate %1 Uniform
  4611. %1 = OpDecorationGroup
  4612. OpGroupMemberDecorate %1 %var 0
  4613. %void = OpTypeVoid
  4614. %func = OpTypeFunction %void
  4615. %uint = OpTypeInt 32 0
  4616. %struct = OpTypeStruct %uint %uint
  4617. %struct_ptr = OpTypePointer Function %struct
  4618. %main = OpFunction %void None %func
  4619. %2 = OpLabel
  4620. %var = OpVariable %struct_ptr Function
  4621. OpReturn
  4622. OpFunctionEnd
  4623. )";
  4624. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  4625. }
  4626. TEST_F(AggressiveDCETest, PartiallyDeadGroupMemberDecorate) {
  4627. const std::string text = R"(
  4628. ; CHECK: OpDecorate [[grp:%\w+]] Offset 0
  4629. ; CHECK: OpDecorate [[grp]] RelaxedPrecision
  4630. ; CHECK: [[grp]] = OpDecorationGroup
  4631. ; CHECK: OpGroupMemberDecorate [[grp]] [[output:%\w+]] 1
  4632. ; CHECK: [[output]] = OpTypeStruct
  4633. ; CHECK-NOT: OpTypeStruct
  4634. OpCapability Shader
  4635. OpMemoryModel Logical GLSL450
  4636. OpEntryPoint Fragment %main "main" %output
  4637. OpExecutionMode %main OriginUpperLeft
  4638. OpDecorate %1 Offset 0
  4639. OpDecorate %1 RelaxedPrecision
  4640. %1 = OpDecorationGroup
  4641. OpGroupMemberDecorate %1 %var_struct 0 %output_struct 1
  4642. %void = OpTypeVoid
  4643. %func = OpTypeFunction %void
  4644. %uint = OpTypeInt 32 0
  4645. %var_struct = OpTypeStruct %uint %uint
  4646. %output_struct = OpTypeStruct %uint %uint
  4647. %struct_ptr_Function = OpTypePointer Function %var_struct
  4648. %struct_ptr_Output = OpTypePointer Output %output_struct
  4649. %uint_ptr_Output = OpTypePointer Output %uint
  4650. %output = OpVariable %struct_ptr_Output Output
  4651. %uint_0 = OpConstant %uint 0
  4652. %main = OpFunction %void None %func
  4653. %2 = OpLabel
  4654. %var = OpVariable %struct_ptr_Function Function
  4655. %3 = OpAccessChain %uint_ptr_Output %output %uint_0
  4656. OpStore %3 %uint_0
  4657. OpReturn
  4658. OpFunctionEnd
  4659. )";
  4660. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  4661. }
  4662. TEST_F(AggressiveDCETest,
  4663. PartiallyDeadGroupMemberDecorateDifferentGroupDecorate) {
  4664. const std::string text = R"(
  4665. ; CHECK: OpDecorate [[grp:%\w+]] Offset 0
  4666. ; CHECK: OpDecorate [[grp]] RelaxedPrecision
  4667. ; CHECK: [[grp]] = OpDecorationGroup
  4668. ; CHECK: OpGroupMemberDecorate [[grp]] [[output:%\w+]] 1
  4669. ; CHECK-NOT: OpGroupMemberDecorate
  4670. ; CHECK: [[output]] = OpTypeStruct
  4671. ; CHECK-NOT: OpTypeStruct
  4672. OpCapability Shader
  4673. OpMemoryModel Logical GLSL450
  4674. OpEntryPoint Fragment %main "main" %output
  4675. OpExecutionMode %main OriginUpperLeft
  4676. OpDecorate %1 Offset 0
  4677. OpDecorate %1 RelaxedPrecision
  4678. %1 = OpDecorationGroup
  4679. OpGroupMemberDecorate %1 %var_struct 0
  4680. OpGroupMemberDecorate %1 %output_struct 1
  4681. %void = OpTypeVoid
  4682. %func = OpTypeFunction %void
  4683. %uint = OpTypeInt 32 0
  4684. %var_struct = OpTypeStruct %uint %uint
  4685. %output_struct = OpTypeStruct %uint %uint
  4686. %struct_ptr_Function = OpTypePointer Function %var_struct
  4687. %struct_ptr_Output = OpTypePointer Output %output_struct
  4688. %uint_ptr_Output = OpTypePointer Output %uint
  4689. %output = OpVariable %struct_ptr_Output Output
  4690. %uint_0 = OpConstant %uint 0
  4691. %main = OpFunction %void None %func
  4692. %2 = OpLabel
  4693. %var = OpVariable %struct_ptr_Function Function
  4694. %3 = OpAccessChain %uint_ptr_Output %output %uint_0
  4695. OpStore %3 %uint_0
  4696. OpReturn
  4697. OpFunctionEnd
  4698. )";
  4699. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  4700. }
  4701. // Test for #1404
  4702. TEST_F(AggressiveDCETest, DontRemoveWorkgroupSize) {
  4703. const std::string text = R"(
  4704. ; CHECK: OpDecorate [[wgs:%\w+]] BuiltIn WorkgroupSize
  4705. ; CHECK: [[wgs]] = OpSpecConstantComposite
  4706. OpCapability Shader
  4707. OpMemoryModel Logical GLSL450
  4708. OpEntryPoint GLCompute %func "func"
  4709. OpExecutionMode %func LocalSize 1 1 1
  4710. OpDecorate %1 BuiltIn WorkgroupSize
  4711. %void = OpTypeVoid
  4712. %int = OpTypeInt 32 0
  4713. %functy = OpTypeFunction %void
  4714. %v3int = OpTypeVector %int 3
  4715. %2 = OpSpecConstant %int 1
  4716. %1 = OpSpecConstantComposite %v3int %2 %2 %2
  4717. %func = OpFunction %void None %functy
  4718. %3 = OpLabel
  4719. OpReturn
  4720. OpFunctionEnd
  4721. )";
  4722. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  4723. }
  4724. // Test for #1214
  4725. TEST_F(AggressiveDCETest, LoopHeaderIsAlsoAnotherLoopMerge) {
  4726. const std::string text = R"(OpCapability Shader
  4727. OpMemoryModel Logical GLSL450
  4728. OpEntryPoint Fragment %1 "func" %2
  4729. OpExecutionMode %1 OriginUpperLeft
  4730. %void = OpTypeVoid
  4731. %bool = OpTypeBool
  4732. %true = OpConstantTrue %bool
  4733. %uint = OpTypeInt 32 0
  4734. %_ptr_Output_uint = OpTypePointer Output %uint
  4735. %2 = OpVariable %_ptr_Output_uint Output
  4736. %uint_0 = OpConstant %uint 0
  4737. %9 = OpTypeFunction %void
  4738. %1 = OpFunction %void None %9
  4739. %10 = OpLabel
  4740. OpBranch %11
  4741. %11 = OpLabel
  4742. OpLoopMerge %12 %13 None
  4743. OpBranchConditional %true %14 %13
  4744. %14 = OpLabel
  4745. OpStore %2 %uint_0
  4746. OpLoopMerge %15 %16 None
  4747. OpBranchConditional %true %15 %16
  4748. %16 = OpLabel
  4749. OpBranch %14
  4750. %15 = OpLabel
  4751. OpBranchConditional %true %12 %13
  4752. %13 = OpLabel
  4753. OpBranch %11
  4754. %12 = OpLabel
  4755. %17 = OpPhi %uint %uint_0 %15 %uint_0 %18
  4756. OpStore %2 %17
  4757. OpLoopMerge %19 %18 None
  4758. OpBranchConditional %true %19 %18
  4759. %18 = OpLabel
  4760. OpBranch %12
  4761. %19 = OpLabel
  4762. OpReturn
  4763. OpFunctionEnd
  4764. )";
  4765. SinglePassRunAndCheck<AggressiveDCEPass>(text, text, true, true);
  4766. }
  4767. TEST_F(AggressiveDCETest, BreaksDontVisitPhis) {
  4768. const std::string text = R"(
  4769. OpCapability Shader
  4770. OpMemoryModel Logical GLSL450
  4771. OpEntryPoint Fragment %func "func" %var
  4772. OpExecutionMode %func OriginUpperLeft
  4773. %void = OpTypeVoid
  4774. %bool = OpTypeBool
  4775. %true = OpConstantTrue %bool
  4776. %int = OpTypeInt 32 0
  4777. %int_ptr_Output = OpTypePointer Output %int
  4778. %var = OpVariable %int_ptr_Output Output
  4779. %int0 = OpConstant %int 0
  4780. %functy = OpTypeFunction %void
  4781. %func = OpFunction %void None %functy
  4782. %entry = OpLabel
  4783. OpBranch %outer_header
  4784. %outer_header = OpLabel
  4785. OpLoopMerge %outer_merge %outer_continue None
  4786. OpBranchConditional %true %inner_header %outer_continue
  4787. %inner_header = OpLabel
  4788. %phi = OpPhi %int %int0 %outer_header %int0 %inner_continue
  4789. OpStore %var %phi
  4790. OpLoopMerge %inner_merge %inner_continue None
  4791. OpBranchConditional %true %inner_merge %inner_continue
  4792. %inner_continue = OpLabel
  4793. OpBranch %inner_header
  4794. %inner_merge = OpLabel
  4795. OpBranch %outer_continue
  4796. %outer_continue = OpLabel
  4797. %p = OpPhi %int %int0 %outer_header %int0 %inner_merge
  4798. OpStore %var %p
  4799. OpBranch %outer_header
  4800. %outer_merge = OpLabel
  4801. OpReturn
  4802. OpFunctionEnd
  4803. )";
  4804. EXPECT_EQ(Pass::Status::SuccessWithoutChange,
  4805. std::get<1>(SinglePassRunAndDisassemble<AggressiveDCEPass>(
  4806. text, false, true)));
  4807. }
  4808. // Test for #1212
  4809. TEST_F(AggressiveDCETest, ConstStoreInnerLoop) {
  4810. const std::string text = R"(OpCapability Shader
  4811. OpMemoryModel Logical GLSL450
  4812. OpEntryPoint Vertex %1 "main" %2
  4813. %void = OpTypeVoid
  4814. %4 = OpTypeFunction %void
  4815. %float = OpTypeFloat 32
  4816. %bool = OpTypeBool
  4817. %true = OpConstantTrue %bool
  4818. %_ptr_Output_float = OpTypePointer Output %float
  4819. %2 = OpVariable %_ptr_Output_float Output
  4820. %float_3 = OpConstant %float 3
  4821. %1 = OpFunction %void None %4
  4822. %13 = OpLabel
  4823. OpBranch %14
  4824. %14 = OpLabel
  4825. OpLoopMerge %15 %16 None
  4826. OpBranchConditional %true %17 %15
  4827. %17 = OpLabel
  4828. OpStore %2 %float_3
  4829. OpLoopMerge %18 %17 None
  4830. OpBranchConditional %true %18 %17
  4831. %18 = OpLabel
  4832. OpBranch %15
  4833. %16 = OpLabel
  4834. OpBranch %14
  4835. %15 = OpLabel
  4836. OpBranch %20
  4837. %20 = OpLabel
  4838. OpReturn
  4839. OpFunctionEnd
  4840. )";
  4841. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  4842. SinglePassRunAndCheck<AggressiveDCEPass>(text, text, true, true);
  4843. }
  4844. // Test for #1212
  4845. TEST_F(AggressiveDCETest, InnerLoopCopy) {
  4846. const std::string text = R"(OpCapability Shader
  4847. OpMemoryModel Logical GLSL450
  4848. OpEntryPoint Vertex %1 "main" %2 %3
  4849. %void = OpTypeVoid
  4850. %5 = OpTypeFunction %void
  4851. %float = OpTypeFloat 32
  4852. %bool = OpTypeBool
  4853. %true = OpConstantTrue %bool
  4854. %_ptr_Output_float = OpTypePointer Output %float
  4855. %_ptr_Input_float = OpTypePointer Input %float
  4856. %2 = OpVariable %_ptr_Output_float Output
  4857. %3 = OpVariable %_ptr_Input_float Input
  4858. %1 = OpFunction %void None %5
  4859. %14 = OpLabel
  4860. OpBranch %15
  4861. %15 = OpLabel
  4862. OpLoopMerge %16 %17 None
  4863. OpBranchConditional %true %18 %16
  4864. %18 = OpLabel
  4865. %19 = OpLoad %float %3
  4866. OpStore %2 %19
  4867. OpLoopMerge %20 %18 None
  4868. OpBranchConditional %true %20 %18
  4869. %20 = OpLabel
  4870. OpBranch %16
  4871. %17 = OpLabel
  4872. OpBranch %15
  4873. %16 = OpLabel
  4874. OpBranch %22
  4875. %22 = OpLabel
  4876. OpReturn
  4877. OpFunctionEnd
  4878. )";
  4879. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  4880. SinglePassRunAndCheck<AggressiveDCEPass>(text, text, true, true);
  4881. }
  4882. TEST_F(AggressiveDCETest, AtomicAdd) {
  4883. const std::string text = R"(OpCapability SampledBuffer
  4884. OpCapability StorageImageExtendedFormats
  4885. OpCapability ImageBuffer
  4886. OpCapability Shader
  4887. %1 = OpExtInstImport "GLSL.std.450"
  4888. OpMemoryModel Logical GLSL450
  4889. OpEntryPoint GLCompute %2 "min"
  4890. OpExecutionMode %2 LocalSize 64 1 1
  4891. OpSource HLSL 600
  4892. OpDecorate %4 DescriptorSet 4
  4893. OpDecorate %4 Binding 70
  4894. %uint = OpTypeInt 32 0
  4895. %6 = OpTypeImage %uint Buffer 0 0 0 2 R32ui
  4896. %_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6
  4897. %_ptr_Private_6 = OpTypePointer Private %6
  4898. %void = OpTypeVoid
  4899. %10 = OpTypeFunction %void
  4900. %uint_0 = OpConstant %uint 0
  4901. %uint_1 = OpConstant %uint 1
  4902. %_ptr_Image_uint = OpTypePointer Image %uint
  4903. %4 = OpVariable %_ptr_UniformConstant_6 UniformConstant
  4904. %16 = OpVariable %_ptr_Private_6 Private
  4905. %2 = OpFunction %void None %10
  4906. %17 = OpLabel
  4907. %18 = OpLoad %6 %4
  4908. OpStore %16 %18
  4909. %19 = OpImageTexelPointer %_ptr_Image_uint %16 %uint_0 %uint_0
  4910. %20 = OpAtomicIAdd %uint %19 %uint_1 %uint_0 %uint_1
  4911. OpReturn
  4912. OpFunctionEnd
  4913. )";
  4914. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  4915. SinglePassRunAndCheck<AggressiveDCEPass>(text, text, true, true);
  4916. }
  4917. TEST_F(AggressiveDCETest, SafelyRemoveDecorateString) {
  4918. const std::string preamble = R"(OpCapability Shader
  4919. OpExtension "SPV_GOOGLE_hlsl_functionality1"
  4920. OpMemoryModel Logical GLSL450
  4921. OpEntryPoint Fragment %1 "main"
  4922. OpExecutionMode %1 OriginUpperLeft
  4923. )";
  4924. const std::string body_before =
  4925. R"(OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "FOOBAR"
  4926. %void = OpTypeVoid
  4927. %4 = OpTypeFunction %void
  4928. %uint = OpTypeInt 32 0
  4929. %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
  4930. %2 = OpVariable %_ptr_StorageBuffer_uint StorageBuffer
  4931. %1 = OpFunction %void None %4
  4932. %7 = OpLabel
  4933. OpReturn
  4934. OpFunctionEnd
  4935. )";
  4936. const std::string body_after = R"(%void = OpTypeVoid
  4937. %4 = OpTypeFunction %void
  4938. %1 = OpFunction %void None %4
  4939. %7 = OpLabel
  4940. OpReturn
  4941. OpFunctionEnd
  4942. )";
  4943. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  4944. SinglePassRunAndCheck<AggressiveDCEPass>(preamble + body_before,
  4945. preamble + body_after, true, true);
  4946. }
  4947. TEST_F(AggressiveDCETest, CopyMemoryToGlobal) {
  4948. // |local| is loaded in an OpCopyMemory instruction. So the store must be
  4949. // kept alive.
  4950. const std::string test =
  4951. R"(OpCapability Geometry
  4952. %1 = OpExtInstImport "GLSL.std.450"
  4953. OpMemoryModel Logical GLSL450
  4954. OpEntryPoint Geometry %main "main" %global
  4955. OpExecutionMode %main Triangles
  4956. OpExecutionMode %main Invocations 1
  4957. OpExecutionMode %main OutputTriangleStrip
  4958. OpExecutionMode %main OutputVertices 5
  4959. OpSource GLSL 440
  4960. OpName %main "main"
  4961. OpName %local "local"
  4962. OpName %global "global"
  4963. %void = OpTypeVoid
  4964. %7 = OpTypeFunction %void
  4965. %float = OpTypeFloat 32
  4966. %v4float = OpTypeVector %float 4
  4967. %12 = OpConstantNull %v4float
  4968. %_ptr_Function_v4float = OpTypePointer Function %v4float
  4969. %_ptr_Output_v4float = OpTypePointer Output %v4float
  4970. %global = OpVariable %_ptr_Output_v4float Output
  4971. %main = OpFunction %void None %7
  4972. %19 = OpLabel
  4973. %local = OpVariable %_ptr_Function_v4float Function
  4974. OpStore %local %12
  4975. OpCopyMemory %global %local
  4976. OpEndPrimitive
  4977. OpReturn
  4978. OpFunctionEnd
  4979. )";
  4980. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  4981. SinglePassRunAndCheck<AggressiveDCEPass>(test, test, true, true);
  4982. }
  4983. TEST_F(AggressiveDCETest, CopyMemoryToLocal) {
  4984. // Make sure the store to |local2| using OpCopyMemory is kept and keeps
  4985. // |local1| alive.
  4986. const std::string test =
  4987. R"(OpCapability Geometry
  4988. %1 = OpExtInstImport "GLSL.std.450"
  4989. OpMemoryModel Logical GLSL450
  4990. OpEntryPoint Geometry %main "main" %global
  4991. OpExecutionMode %main Triangles
  4992. OpExecutionMode %main Invocations 1
  4993. OpExecutionMode %main OutputTriangleStrip
  4994. OpExecutionMode %main OutputVertices 5
  4995. OpSource GLSL 440
  4996. OpName %main "main"
  4997. OpName %local1 "local1"
  4998. OpName %local2 "local2"
  4999. OpName %global "global"
  5000. %void = OpTypeVoid
  5001. %7 = OpTypeFunction %void
  5002. %float = OpTypeFloat 32
  5003. %v4float = OpTypeVector %float 4
  5004. %12 = OpConstantNull %v4float
  5005. %_ptr_Function_v4float = OpTypePointer Function %v4float
  5006. %_ptr_Output_v4float = OpTypePointer Output %v4float
  5007. %global = OpVariable %_ptr_Output_v4float Output
  5008. %main = OpFunction %void None %7
  5009. %19 = OpLabel
  5010. %local1 = OpVariable %_ptr_Function_v4float Function
  5011. %local2 = OpVariable %_ptr_Function_v4float Function
  5012. OpStore %local1 %12
  5013. OpCopyMemory %local2 %local1
  5014. OpCopyMemory %global %local2
  5015. OpEndPrimitive
  5016. OpReturn
  5017. OpFunctionEnd
  5018. )";
  5019. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  5020. SinglePassRunAndCheck<AggressiveDCEPass>(test, test, true, true);
  5021. }
  5022. TEST_F(AggressiveDCETest, RemoveCopyMemoryToLocal) {
  5023. // Test that we remove function scope variables that are stored to using
  5024. // OpCopyMemory, but are never loaded. We can remove both |local1| and
  5025. // |local2|.
  5026. const std::string test =
  5027. R"(OpCapability Geometry
  5028. %1 = OpExtInstImport "GLSL.std.450"
  5029. OpMemoryModel Logical GLSL450
  5030. OpEntryPoint Geometry %main "main" %global
  5031. OpExecutionMode %main Triangles
  5032. OpExecutionMode %main Invocations 1
  5033. OpExecutionMode %main OutputTriangleStrip
  5034. OpExecutionMode %main OutputVertices 5
  5035. OpSource GLSL 440
  5036. OpName %main "main"
  5037. OpName %local1 "local1"
  5038. OpName %local2 "local2"
  5039. OpName %global "global"
  5040. %void = OpTypeVoid
  5041. %7 = OpTypeFunction %void
  5042. %float = OpTypeFloat 32
  5043. %v4float = OpTypeVector %float 4
  5044. %12 = OpConstantNull %v4float
  5045. %_ptr_Function_v4float = OpTypePointer Function %v4float
  5046. %_ptr_Output_v4float = OpTypePointer Output %v4float
  5047. %global = OpVariable %_ptr_Output_v4float Output
  5048. %main = OpFunction %void None %7
  5049. %19 = OpLabel
  5050. %local1 = OpVariable %_ptr_Function_v4float Function
  5051. %local2 = OpVariable %_ptr_Function_v4float Function
  5052. OpStore %local1 %12
  5053. OpCopyMemory %local2 %local1
  5054. OpEndPrimitive
  5055. OpReturn
  5056. OpFunctionEnd
  5057. )";
  5058. const std::string result =
  5059. R"(OpCapability Geometry
  5060. %1 = OpExtInstImport "GLSL.std.450"
  5061. OpMemoryModel Logical GLSL450
  5062. OpEntryPoint Geometry %main "main" %global
  5063. OpExecutionMode %main Triangles
  5064. OpExecutionMode %main Invocations 1
  5065. OpExecutionMode %main OutputTriangleStrip
  5066. OpExecutionMode %main OutputVertices 5
  5067. OpSource GLSL 440
  5068. OpName %main "main"
  5069. OpName %global "global"
  5070. %void = OpTypeVoid
  5071. %7 = OpTypeFunction %void
  5072. %float = OpTypeFloat 32
  5073. %v4float = OpTypeVector %float 4
  5074. %_ptr_Output_v4float = OpTypePointer Output %v4float
  5075. %global = OpVariable %_ptr_Output_v4float Output
  5076. %main = OpFunction %void None %7
  5077. %19 = OpLabel
  5078. OpEndPrimitive
  5079. OpReturn
  5080. OpFunctionEnd
  5081. )";
  5082. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  5083. SinglePassRunAndCheck<AggressiveDCEPass>(test, result, true, true);
  5084. }
  5085. TEST_F(AggressiveDCETest, RemoveCopyMemoryToLocal2) {
  5086. // We are able to remove "local2" because it is not loaded, but have to keep
  5087. // the stores to "local1".
  5088. const std::string test =
  5089. R"(OpCapability Geometry
  5090. %1 = OpExtInstImport "GLSL.std.450"
  5091. OpMemoryModel Logical GLSL450
  5092. OpEntryPoint Geometry %main "main" %global
  5093. OpExecutionMode %main Triangles
  5094. OpExecutionMode %main Invocations 1
  5095. OpExecutionMode %main OutputTriangleStrip
  5096. OpExecutionMode %main OutputVertices 5
  5097. OpSource GLSL 440
  5098. OpName %main "main"
  5099. OpName %local1 "local1"
  5100. OpName %local2 "local2"
  5101. OpName %global "global"
  5102. %void = OpTypeVoid
  5103. %7 = OpTypeFunction %void
  5104. %float = OpTypeFloat 32
  5105. %v4float = OpTypeVector %float 4
  5106. %12 = OpConstantNull %v4float
  5107. %_ptr_Function_v4float = OpTypePointer Function %v4float
  5108. %_ptr_Output_v4float = OpTypePointer Output %v4float
  5109. %global = OpVariable %_ptr_Output_v4float Output
  5110. %main = OpFunction %void None %7
  5111. %19 = OpLabel
  5112. %local1 = OpVariable %_ptr_Function_v4float Function
  5113. %local2 = OpVariable %_ptr_Function_v4float Function
  5114. OpStore %local1 %12
  5115. OpCopyMemory %local2 %local1
  5116. OpCopyMemory %global %local1
  5117. OpEndPrimitive
  5118. OpReturn
  5119. OpFunctionEnd
  5120. )";
  5121. const std::string result =
  5122. R"(OpCapability Geometry
  5123. %1 = OpExtInstImport "GLSL.std.450"
  5124. OpMemoryModel Logical GLSL450
  5125. OpEntryPoint Geometry %main "main" %global
  5126. OpExecutionMode %main Triangles
  5127. OpExecutionMode %main Invocations 1
  5128. OpExecutionMode %main OutputTriangleStrip
  5129. OpExecutionMode %main OutputVertices 5
  5130. OpSource GLSL 440
  5131. OpName %main "main"
  5132. OpName %local1 "local1"
  5133. OpName %global "global"
  5134. %void = OpTypeVoid
  5135. %7 = OpTypeFunction %void
  5136. %float = OpTypeFloat 32
  5137. %v4float = OpTypeVector %float 4
  5138. %12 = OpConstantNull %v4float
  5139. %_ptr_Function_v4float = OpTypePointer Function %v4float
  5140. %_ptr_Output_v4float = OpTypePointer Output %v4float
  5141. %global = OpVariable %_ptr_Output_v4float Output
  5142. %main = OpFunction %void None %7
  5143. %19 = OpLabel
  5144. %local1 = OpVariable %_ptr_Function_v4float Function
  5145. OpStore %local1 %12
  5146. OpCopyMemory %global %local1
  5147. OpEndPrimitive
  5148. OpReturn
  5149. OpFunctionEnd
  5150. )";
  5151. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  5152. SinglePassRunAndCheck<AggressiveDCEPass>(test, result, true, true);
  5153. }
  5154. TEST_F(AggressiveDCETest, StructuredIfWithConditionalExit) {
  5155. // We are able to remove "local2" because it is not loaded, but have to keep
  5156. // the stores to "local1".
  5157. const std::string test =
  5158. R"(OpCapability Shader
  5159. %1 = OpExtInstImport "GLSL.std.450"
  5160. OpMemoryModel Logical GLSL450
  5161. OpEntryPoint Fragment %main "main"
  5162. OpExecutionMode %main OriginUpperLeft
  5163. OpSource GLSL 140
  5164. OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
  5165. OpSourceExtension "GL_GOOGLE_include_directive"
  5166. OpName %main "main"
  5167. OpName %a "a"
  5168. %void = OpTypeVoid
  5169. %5 = OpTypeFunction %void
  5170. %int = OpTypeInt 32 1
  5171. %_ptr_Uniform_int = OpTypePointer Uniform %int
  5172. %int_0 = OpConstant %int 0
  5173. %bool = OpTypeBool
  5174. %int_100 = OpConstant %int 100
  5175. %int_1 = OpConstant %int 1
  5176. %a = OpVariable %_ptr_Uniform_int Uniform
  5177. %main = OpFunction %void None %5
  5178. %12 = OpLabel
  5179. %13 = OpLoad %int %a
  5180. %14 = OpSGreaterThan %bool %13 %int_0
  5181. OpSelectionMerge %15 None
  5182. OpBranchConditional %14 %16 %15
  5183. %16 = OpLabel
  5184. %17 = OpLoad %int %a
  5185. %18 = OpSLessThan %bool %17 %int_100
  5186. OpBranchConditional %18 %19 %15
  5187. %19 = OpLabel
  5188. OpStore %a %int_1
  5189. OpBranch %15
  5190. %15 = OpLabel
  5191. OpReturn
  5192. OpFunctionEnd
  5193. )";
  5194. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  5195. SinglePassRunAndCheck<AggressiveDCEPass>(test, test, true, true);
  5196. }
  5197. TEST_F(AggressiveDCETest, CountingLoopNotEliminated) {
  5198. // #version 310 es
  5199. //
  5200. // precision highp float;
  5201. // precision highp int;
  5202. //
  5203. // layout(location = 0) out vec4 _GLF_color;
  5204. //
  5205. // void main()
  5206. // {
  5207. // float data[1];
  5208. // for (int c = 0; c < 1; c++) {
  5209. // if (true) {
  5210. // do {
  5211. // for (int i = 0; i < 1; i++) {
  5212. // data[i] = 1.0;
  5213. // }
  5214. // } while (false);
  5215. // }
  5216. // }
  5217. // _GLF_color = vec4(data[0], 0.0, 0.0, 1.0);
  5218. // }
  5219. const std::string test =
  5220. R"(OpCapability Shader
  5221. %1 = OpExtInstImport "GLSL.std.450"
  5222. OpMemoryModel Logical GLSL450
  5223. OpEntryPoint Fragment %main "main" %_GLF_color
  5224. OpExecutionMode %main OriginUpperLeft
  5225. OpSource ESSL 310
  5226. OpName %main "main"
  5227. OpName %c "c"
  5228. OpName %i "i"
  5229. OpName %data "data"
  5230. OpName %_GLF_color "_GLF_color"
  5231. OpDecorate %_GLF_color Location 0
  5232. %void = OpTypeVoid
  5233. %8 = OpTypeFunction %void
  5234. %int = OpTypeInt 32 1
  5235. %_ptr_Function_int = OpTypePointer Function %int
  5236. %int_0 = OpConstant %int 0
  5237. %int_1 = OpConstant %int 1
  5238. %bool = OpTypeBool
  5239. %float = OpTypeFloat 32
  5240. %uint = OpTypeInt 32 0
  5241. %uint_1 = OpConstant %uint 1
  5242. %_arr_float_uint_1 = OpTypeArray %float %uint_1
  5243. %_ptr_Function__arr_float_uint_1 = OpTypePointer Function %_arr_float_uint_1
  5244. %float_1 = OpConstant %float 1
  5245. %_ptr_Function_float = OpTypePointer Function %float
  5246. %false = OpConstantFalse %bool
  5247. %v4float = OpTypeVector %float 4
  5248. %_ptr_Output_v4float = OpTypePointer Output %v4float
  5249. %_GLF_color = OpVariable %_ptr_Output_v4float Output
  5250. %float_0 = OpConstant %float 0
  5251. %main = OpFunction %void None %8
  5252. %26 = OpLabel
  5253. %c = OpVariable %_ptr_Function_int Function
  5254. %i = OpVariable %_ptr_Function_int Function
  5255. %data = OpVariable %_ptr_Function__arr_float_uint_1 Function
  5256. OpStore %c %int_0
  5257. OpBranch %27
  5258. %27 = OpLabel
  5259. OpLoopMerge %28 %29 None
  5260. OpBranch %30
  5261. %30 = OpLabel
  5262. %31 = OpLoad %int %c
  5263. %32 = OpSLessThan %bool %31 %int_1
  5264. OpBranchConditional %32 %33 %28
  5265. %33 = OpLabel
  5266. OpBranch %34
  5267. %34 = OpLabel
  5268. OpBranch %35
  5269. %35 = OpLabel
  5270. OpLoopMerge %36 %37 None
  5271. OpBranch %38
  5272. %38 = OpLabel
  5273. OpStore %i %int_0
  5274. OpBranch %39
  5275. %39 = OpLabel
  5276. OpLoopMerge %40 %41 None
  5277. OpBranch %42
  5278. %42 = OpLabel
  5279. %43 = OpLoad %int %i
  5280. %44 = OpSLessThan %bool %43 %int_1
  5281. OpBranchConditional %44 %46 %40
  5282. %46 = OpLabel
  5283. %47 = OpLoad %int %i
  5284. %48 = OpAccessChain %_ptr_Function_float %data %47
  5285. OpStore %48 %float_1
  5286. OpBranch %41
  5287. %41 = OpLabel
  5288. %49 = OpLoad %int %i
  5289. %50 = OpIAdd %int %49 %int_1
  5290. OpStore %i %50
  5291. OpBranch %39
  5292. %40 = OpLabel
  5293. OpBranch %37
  5294. %37 = OpLabel
  5295. OpBranchConditional %false %35 %36
  5296. %36 = OpLabel
  5297. OpBranch %45
  5298. %45 = OpLabel
  5299. OpBranch %29
  5300. %29 = OpLabel
  5301. %51 = OpLoad %int %c
  5302. %52 = OpIAdd %int %51 %int_1
  5303. OpStore %c %52
  5304. OpBranch %27
  5305. %28 = OpLabel
  5306. %53 = OpAccessChain %_ptr_Function_float %data %int_0
  5307. %54 = OpLoad %float %53
  5308. %55 = OpCompositeConstruct %v4float %54 %float_0 %float_0 %float_1
  5309. OpStore %_GLF_color %55
  5310. OpReturn
  5311. OpFunctionEnd
  5312. )";
  5313. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  5314. SinglePassRunAndCheck<AggressiveDCEPass>(test, test, true, true);
  5315. }
  5316. TEST_F(AggressiveDCETest, EliminateLoopWithUnreachable) {
  5317. // #version 430
  5318. //
  5319. // layout(std430) buffer U_t
  5320. // {
  5321. // float g_F[10];
  5322. // float g_S;
  5323. // };
  5324. //
  5325. // layout(location = 0)out float o;
  5326. //
  5327. // void main(void)
  5328. // {
  5329. // // Useless loop
  5330. // for (int i = 0; i<10; i++) {
  5331. // if (g_F[i] == 0.0)
  5332. // break;
  5333. // else
  5334. // break;
  5335. // // Unreachable merge block created here.
  5336. // // Need to edit SPIR-V to change to OpUnreachable
  5337. // }
  5338. // o = g_S;
  5339. // }
  5340. const std::string before =
  5341. R"(OpCapability Shader
  5342. %1 = OpExtInstImport "GLSL.std.450"
  5343. OpMemoryModel Logical GLSL450
  5344. OpEntryPoint Fragment %main "main" %o
  5345. OpExecutionMode %main OriginUpperLeft
  5346. OpSource GLSL 430
  5347. OpName %main "main"
  5348. OpName %i "i"
  5349. OpName %U_t "U_t"
  5350. OpMemberName %U_t 0 "g_F"
  5351. OpMemberName %U_t 1 "g_S"
  5352. OpName %_ ""
  5353. OpName %o "o"
  5354. OpDecorate %_arr_float_uint_10 ArrayStride 4
  5355. OpMemberDecorate %U_t 0 Offset 0
  5356. OpMemberDecorate %U_t 1 Offset 40
  5357. OpDecorate %U_t BufferBlock
  5358. OpDecorate %_ DescriptorSet 0
  5359. OpDecorate %o Location 0
  5360. %void = OpTypeVoid
  5361. %9 = OpTypeFunction %void
  5362. %int = OpTypeInt 32 1
  5363. %_ptr_Function_int = OpTypePointer Function %int
  5364. %int_0 = OpConstant %int 0
  5365. %int_10 = OpConstant %int 10
  5366. %bool = OpTypeBool
  5367. %float = OpTypeFloat 32
  5368. %uint = OpTypeInt 32 0
  5369. %uint_10 = OpConstant %uint 10
  5370. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  5371. %U_t = OpTypeStruct %_arr_float_uint_10 %float
  5372. %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
  5373. %_ = OpVariable %_ptr_Uniform_U_t Uniform
  5374. %_ptr_Uniform_float = OpTypePointer Uniform %float
  5375. %float_0 = OpConstant %float 0
  5376. %int_1 = OpConstant %int 1
  5377. %_ptr_Output_float = OpTypePointer Output %float
  5378. %o = OpVariable %_ptr_Output_float Output
  5379. %main = OpFunction %void None %9
  5380. %23 = OpLabel
  5381. %i = OpVariable %_ptr_Function_int Function
  5382. OpStore %i %int_0
  5383. OpBranch %24
  5384. %24 = OpLabel
  5385. OpLoopMerge %25 %26 None
  5386. OpBranch %27
  5387. %27 = OpLabel
  5388. %28 = OpLoad %int %i
  5389. %29 = OpSLessThan %bool %28 %int_10
  5390. OpBranchConditional %29 %30 %25
  5391. %30 = OpLabel
  5392. %31 = OpLoad %int %i
  5393. %32 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %31
  5394. %33 = OpLoad %float %32
  5395. %34 = OpFOrdEqual %bool %33 %float_0
  5396. OpSelectionMerge %35 None
  5397. OpBranchConditional %34 %36 %37
  5398. %36 = OpLabel
  5399. OpBranch %25
  5400. %37 = OpLabel
  5401. OpBranch %25
  5402. %35 = OpLabel
  5403. OpUnreachable
  5404. %26 = OpLabel
  5405. %38 = OpLoad %int %i
  5406. %39 = OpIAdd %int %38 %int_1
  5407. OpStore %i %39
  5408. OpBranch %24
  5409. %25 = OpLabel
  5410. %40 = OpAccessChain %_ptr_Uniform_float %_ %int_1
  5411. %41 = OpLoad %float %40
  5412. OpStore %o %41
  5413. OpReturn
  5414. OpFunctionEnd
  5415. )";
  5416. const std::string after =
  5417. R"(OpCapability Shader
  5418. %1 = OpExtInstImport "GLSL.std.450"
  5419. OpMemoryModel Logical GLSL450
  5420. OpEntryPoint Fragment %main "main" %o
  5421. OpExecutionMode %main OriginUpperLeft
  5422. OpSource GLSL 430
  5423. OpName %main "main"
  5424. OpName %U_t "U_t"
  5425. OpMemberName %U_t 0 "g_F"
  5426. OpMemberName %U_t 1 "g_S"
  5427. OpName %_ ""
  5428. OpName %o "o"
  5429. OpDecorate %_arr_float_uint_10 ArrayStride 4
  5430. OpMemberDecorate %U_t 0 Offset 0
  5431. OpMemberDecorate %U_t 1 Offset 40
  5432. OpDecorate %U_t BufferBlock
  5433. OpDecorate %_ DescriptorSet 0
  5434. OpDecorate %o Location 0
  5435. %void = OpTypeVoid
  5436. %9 = OpTypeFunction %void
  5437. %int = OpTypeInt 32 1
  5438. %float = OpTypeFloat 32
  5439. %uint = OpTypeInt 32 0
  5440. %uint_10 = OpConstant %uint 10
  5441. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  5442. %U_t = OpTypeStruct %_arr_float_uint_10 %float
  5443. %_ptr_Uniform_U_t = OpTypePointer Uniform %U_t
  5444. %_ = OpVariable %_ptr_Uniform_U_t Uniform
  5445. %_ptr_Uniform_float = OpTypePointer Uniform %float
  5446. %int_1 = OpConstant %int 1
  5447. %_ptr_Output_float = OpTypePointer Output %float
  5448. %o = OpVariable %_ptr_Output_float Output
  5449. %main = OpFunction %void None %9
  5450. %23 = OpLabel
  5451. OpBranch %24
  5452. %24 = OpLabel
  5453. OpBranch %25
  5454. %25 = OpLabel
  5455. %40 = OpAccessChain %_ptr_Uniform_float %_ %int_1
  5456. %41 = OpLoad %float %40
  5457. OpStore %o %41
  5458. OpReturn
  5459. OpFunctionEnd
  5460. )";
  5461. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  5462. SinglePassRunAndCheck<AggressiveDCEPass>(before, after, true, true);
  5463. }
  5464. TEST_F(AggressiveDCETest, DeadHlslCounterBufferGOOGLE) {
  5465. // We are able to remove "local2" because it is not loaded, but have to keep
  5466. // the stores to "local1".
  5467. const std::string test =
  5468. R"(
  5469. ; CHECK-NOT: OpDecorateId
  5470. ; CHECK: [[var:%\w+]] = OpVariable
  5471. ; CHECK-NOT: OpVariable
  5472. ; CHECK: [[ac:%\w+]] = OpAccessChain {{%\w+}} [[var]]
  5473. ; CHECK: OpStore [[ac]]
  5474. OpCapability Shader
  5475. OpExtension "SPV_GOOGLE_hlsl_functionality1"
  5476. OpMemoryModel Logical GLSL450
  5477. OpEntryPoint GLCompute %1 "main"
  5478. OpExecutionMode %1 LocalSize 32 1 1
  5479. OpSource HLSL 600
  5480. OpDecorate %_runtimearr_v2float ArrayStride 8
  5481. OpMemberDecorate %_struct_3 0 Offset 0
  5482. OpDecorate %_struct_3 BufferBlock
  5483. OpMemberDecorate %_struct_4 0 Offset 0
  5484. OpDecorate %_struct_4 BufferBlock
  5485. OpDecorateId %5 HlslCounterBufferGOOGLE %6
  5486. OpDecorate %5 DescriptorSet 0
  5487. OpDecorate %5 Binding 0
  5488. OpDecorate %6 DescriptorSet 0
  5489. OpDecorate %6 Binding 1
  5490. %float = OpTypeFloat 32
  5491. %v2float = OpTypeVector %float 2
  5492. %_runtimearr_v2float = OpTypeRuntimeArray %v2float
  5493. %_struct_3 = OpTypeStruct %_runtimearr_v2float
  5494. %_ptr_Uniform__struct_3 = OpTypePointer Uniform %_struct_3
  5495. %int = OpTypeInt 32 1
  5496. %_struct_4 = OpTypeStruct %int
  5497. %_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4
  5498. %void = OpTypeVoid
  5499. %13 = OpTypeFunction %void
  5500. %19 = OpConstantNull %v2float
  5501. %int_0 = OpConstant %int 0
  5502. %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
  5503. %5 = OpVariable %_ptr_Uniform__struct_3 Uniform
  5504. %6 = OpVariable %_ptr_Uniform__struct_4 Uniform
  5505. %1 = OpFunction %void None %13
  5506. %22 = OpLabel
  5507. %23 = OpAccessChain %_ptr_Uniform_v2float %5 %int_0 %int_0
  5508. OpStore %23 %19
  5509. OpReturn
  5510. OpFunctionEnd
  5511. )";
  5512. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  5513. SinglePassRunAndMatch<AggressiveDCEPass>(test, true);
  5514. }
  5515. TEST_F(AggressiveDCETest, Dead) {
  5516. // We are able to remove "local2" because it is not loaded, but have to keep
  5517. // the stores to "local1".
  5518. const std::string test =
  5519. R"(
  5520. ; CHECK: OpCapability
  5521. ; CHECK-NOT: OpMemberDecorateStringGOOGLE
  5522. ; CHECK: OpFunctionEnd
  5523. OpCapability Shader
  5524. OpExtension "SPV_GOOGLE_hlsl_functionality1"
  5525. %1 = OpExtInstImport "GLSL.std.450"
  5526. OpMemoryModel Logical GLSL450
  5527. OpEntryPoint Vertex %VSMain "VSMain"
  5528. OpSource HLSL 500
  5529. OpName %VSMain "VSMain"
  5530. OpName %PSInput "PSInput"
  5531. OpMemberName %PSInput 0 "Pos"
  5532. OpMemberName %PSInput 1 "uv"
  5533. OpMemberDecorateStringGOOGLE %PSInput 0 HlslSemanticGOOGLE "SV_POSITION"
  5534. OpMemberDecorateStringGOOGLE %PSInput 1 HlslSemanticGOOGLE "TEX_COORD"
  5535. %void = OpTypeVoid
  5536. %5 = OpTypeFunction %void
  5537. %float = OpTypeFloat 32
  5538. %v2float = OpTypeVector %float 2
  5539. %v4float = OpTypeVector %float 4
  5540. %PSInput = OpTypeStruct %v4float %v2float
  5541. %VSMain = OpFunction %void None %5
  5542. %9 = OpLabel
  5543. OpReturn
  5544. OpFunctionEnd
  5545. )";
  5546. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  5547. SinglePassRunAndMatch<AggressiveDCEPass>(test, true);
  5548. }
  5549. TEST_F(AggressiveDCETest, DeadInfiniteLoop) {
  5550. const std::string test = R"(
  5551. ; CHECK: OpSwitch {{%\w+}} {{%\w+}} {{\w+}} {{%\w+}} {{\w+}} [[block:%\w+]]
  5552. ; CHECK: [[block]] = OpLabel
  5553. ; CHECK-NEXT: OpBranch [[block:%\w+]]
  5554. ; CHECK: [[block]] = OpLabel
  5555. ; CHECK-NEXT: OpBranch [[block:%\w+]]
  5556. ; CHECK: [[block]] = OpLabel
  5557. ; CHECK-NEXT: OpReturn
  5558. OpCapability Shader
  5559. OpMemoryModel Logical GLSL450
  5560. OpEntryPoint Fragment %2 "main"
  5561. OpExecutionMode %2 OriginUpperLeft
  5562. %6 = OpTypeVoid
  5563. %7 = OpTypeFunction %6
  5564. %8 = OpTypeFloat 32
  5565. %9 = OpTypeVector %8 3
  5566. %10 = OpTypeFunction %9
  5567. %11 = OpConstant %8 1
  5568. %12 = OpConstantComposite %9 %11 %11 %11
  5569. %13 = OpTypeInt 32 1
  5570. %32 = OpUndef %13
  5571. %2 = OpFunction %6 None %7
  5572. %33 = OpLabel
  5573. OpBranch %34
  5574. %34 = OpLabel
  5575. OpLoopMerge %35 %36 None
  5576. OpBranch %37
  5577. %37 = OpLabel
  5578. %38 = OpFunctionCall %9 %39
  5579. OpSelectionMerge %40 None
  5580. OpSwitch %32 %40 14 %41 58 %42
  5581. %42 = OpLabel
  5582. OpBranch %43
  5583. %43 = OpLabel
  5584. OpLoopMerge %44 %45 None
  5585. OpBranch %45
  5586. %45 = OpLabel
  5587. OpBranch %43
  5588. %44 = OpLabel
  5589. OpUnreachable
  5590. %41 = OpLabel
  5591. OpBranch %36
  5592. %40 = OpLabel
  5593. OpBranch %36
  5594. %36 = OpLabel
  5595. OpBranch %34
  5596. %35 = OpLabel
  5597. OpReturn
  5598. OpFunctionEnd
  5599. %39 = OpFunction %9 None %10
  5600. %46 = OpLabel
  5601. OpReturnValue %12
  5602. OpFunctionEnd
  5603. )";
  5604. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  5605. SinglePassRunAndMatch<AggressiveDCEPass>(test, true);
  5606. }
  5607. TEST_F(AggressiveDCETest, DeadInfiniteLoopReturnValue) {
  5608. const std::string test = R"(
  5609. ; CHECK: [[vec3:%\w+]] = OpTypeVector
  5610. ; CHECK: [[undef:%\w+]] = OpUndef [[vec3]]
  5611. ; CHECK: OpSwitch {{%\w+}} {{%\w+}} {{\w+}} {{%\w+}} {{\w+}} [[block:%\w+]]
  5612. ; CHECK: [[block]] = OpLabel
  5613. ; CHECK-NEXT: OpBranch [[block:%\w+]]
  5614. ; CHECK: [[block]] = OpLabel
  5615. ; CHECK-NEXT: OpBranch [[block:%\w+]]
  5616. ; CHECK: [[block]] = OpLabel
  5617. ; CHECK-NEXT: OpReturnValue [[undef]]
  5618. OpCapability Shader
  5619. OpMemoryModel Logical GLSL450
  5620. OpEntryPoint Fragment %2 "main"
  5621. OpExecutionMode %2 OriginUpperLeft
  5622. %6 = OpTypeVoid
  5623. %7 = OpTypeFunction %6
  5624. %8 = OpTypeFloat 32
  5625. %9 = OpTypeVector %8 3
  5626. %10 = OpTypeFunction %9
  5627. %11 = OpConstant %8 1
  5628. %12 = OpConstantComposite %9 %11 %11 %11
  5629. %13 = OpTypeInt 32 1
  5630. %32 = OpUndef %13
  5631. %2 = OpFunction %6 None %7
  5632. %entry = OpLabel
  5633. %call = OpFunctionCall %9 %func
  5634. OpReturn
  5635. OpFunctionEnd
  5636. %func = OpFunction %9 None %10
  5637. %33 = OpLabel
  5638. OpBranch %34
  5639. %34 = OpLabel
  5640. OpLoopMerge %35 %36 None
  5641. OpBranch %37
  5642. %37 = OpLabel
  5643. %38 = OpFunctionCall %9 %39
  5644. OpSelectionMerge %40 None
  5645. OpSwitch %32 %40 14 %41 58 %42
  5646. %42 = OpLabel
  5647. OpBranch %43
  5648. %43 = OpLabel
  5649. OpLoopMerge %44 %45 None
  5650. OpBranch %45
  5651. %45 = OpLabel
  5652. OpBranch %43
  5653. %44 = OpLabel
  5654. OpUnreachable
  5655. %41 = OpLabel
  5656. OpBranch %36
  5657. %40 = OpLabel
  5658. OpBranch %36
  5659. %36 = OpLabel
  5660. OpBranch %34
  5661. %35 = OpLabel
  5662. OpReturnValue %12
  5663. OpFunctionEnd
  5664. %39 = OpFunction %9 None %10
  5665. %46 = OpLabel
  5666. OpReturnValue %12
  5667. OpFunctionEnd
  5668. )";
  5669. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  5670. SinglePassRunAndMatch<AggressiveDCEPass>(test, true);
  5671. }
  5672. TEST_F(AggressiveDCETest, TestVariablePointer) {
  5673. const std::string before =
  5674. R"(OpCapability Shader
  5675. OpCapability VariablePointers
  5676. %1 = OpExtInstImport "GLSL.std.450"
  5677. OpMemoryModel Logical GLSL450
  5678. OpEntryPoint GLCompute %2 "main"
  5679. OpExecutionMode %2 LocalSize 1 1 1
  5680. OpSource GLSL 450
  5681. OpMemberDecorate %_struct_3 0 Offset 0
  5682. OpDecorate %_struct_3 Block
  5683. OpDecorate %4 DescriptorSet 0
  5684. OpDecorate %4 Binding 0
  5685. OpDecorate %_ptr_StorageBuffer_int ArrayStride 4
  5686. OpDecorate %_arr_int_int_128 ArrayStride 4
  5687. %void = OpTypeVoid
  5688. %8 = OpTypeFunction %void
  5689. %int = OpTypeInt 32 1
  5690. %int_128 = OpConstant %int 128
  5691. %_arr_int_int_128 = OpTypeArray %int %int_128
  5692. %_struct_3 = OpTypeStruct %_arr_int_int_128
  5693. %_ptr_StorageBuffer__struct_3 = OpTypePointer StorageBuffer %_struct_3
  5694. %4 = OpVariable %_ptr_StorageBuffer__struct_3 StorageBuffer
  5695. %bool = OpTypeBool
  5696. %true = OpConstantTrue %bool
  5697. %int_0 = OpConstant %int 0
  5698. %int_1 = OpConstant %int 1
  5699. %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
  5700. %2 = OpFunction %void None %8
  5701. %16 = OpLabel
  5702. %17 = OpAccessChain %_ptr_StorageBuffer_int %4 %int_0 %int_0
  5703. OpBranch %18
  5704. %18 = OpLabel
  5705. %19 = OpPhi %_ptr_StorageBuffer_int %17 %16 %20 %21
  5706. OpLoopMerge %22 %21 None
  5707. OpBranchConditional %true %23 %22
  5708. %23 = OpLabel
  5709. OpStore %19 %int_0
  5710. OpBranch %21
  5711. %21 = OpLabel
  5712. %20 = OpPtrAccessChain %_ptr_StorageBuffer_int %19 %int_1
  5713. OpBranch %18
  5714. %22 = OpLabel
  5715. OpReturn
  5716. OpFunctionEnd
  5717. )";
  5718. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  5719. SinglePassRunAndCheck<AggressiveDCEPass>(before, before, true, true);
  5720. }
  5721. TEST_F(AggressiveDCETest, DeadInputInterfaceV13) {
  5722. const std::string spirv = R"(
  5723. ; CHECK: OpEntryPoint GLCompute %main "main"
  5724. ; CHECK-NOT: OpVariable
  5725. OpCapability Shader
  5726. OpMemoryModel Logical GLSL450
  5727. OpEntryPoint GLCompute %main "main" %dead
  5728. OpExecutionMode %main LocalSize 1 1 1
  5729. OpName %main "main"
  5730. %void = OpTypeVoid
  5731. %int = OpTypeInt 32 0
  5732. %ptr_input_int = OpTypePointer Input %int
  5733. %dead = OpVariable %ptr_input_int Input
  5734. %void_fn = OpTypeFunction %void
  5735. %main = OpFunction %void None %void_fn
  5736. %entry = OpLabel
  5737. OpReturn
  5738. OpFunctionEnd
  5739. )";
  5740. SetTargetEnv(SPV_ENV_UNIVERSAL_1_3);
  5741. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  5742. }
  5743. TEST_F(AggressiveDCETest, DeadInputInterfaceV14) {
  5744. const std::string spirv = R"(
  5745. ; CHECK: OpEntryPoint GLCompute %main "main"
  5746. ; CHECK-NOT: OpVariable
  5747. OpCapability Shader
  5748. OpMemoryModel Logical GLSL450
  5749. OpEntryPoint GLCompute %main "main" %dead
  5750. OpExecutionMode %main LocalSize 1 1 1
  5751. OpName %main "main"
  5752. %void = OpTypeVoid
  5753. %int = OpTypeInt 32 0
  5754. %ptr_input_int = OpTypePointer Input %int
  5755. %dead = OpVariable %ptr_input_int Input
  5756. %void_fn = OpTypeFunction %void
  5757. %main = OpFunction %void None %void_fn
  5758. %entry = OpLabel
  5759. OpReturn
  5760. OpFunctionEnd
  5761. )";
  5762. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  5763. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  5764. }
  5765. TEST_F(AggressiveDCETest, DeadInterfaceV14) {
  5766. const std::string spirv = R"(
  5767. ; CHECK-NOT: OpEntryPoint GLCompute %main "main" %
  5768. ; CHECK: OpEntryPoint GLCompute %main "main"
  5769. ; CHECK-NOT: OpVariable
  5770. OpCapability Shader
  5771. OpMemoryModel Logical GLSL450
  5772. OpEntryPoint GLCompute %main "main" %dead
  5773. OpExecutionMode %main LocalSize 1 1 1
  5774. OpName %main "main"
  5775. %void = OpTypeVoid
  5776. %int = OpTypeInt 32 0
  5777. %ptr_private_int = OpTypePointer Private %int
  5778. %dead = OpVariable %ptr_private_int Private
  5779. %void_fn = OpTypeFunction %void
  5780. %main = OpFunction %void None %void_fn
  5781. %entry = OpLabel
  5782. OpReturn
  5783. OpFunctionEnd
  5784. )";
  5785. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  5786. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  5787. }
  5788. TEST_F(AggressiveDCETest, DeadInterfacesV14) {
  5789. const std::string spirv = R"(
  5790. ; CHECK: OpEntryPoint GLCompute %main "main" %live1 %live2
  5791. ; CHECK-NOT: %dead
  5792. OpCapability Shader
  5793. OpMemoryModel Logical GLSL450
  5794. OpEntryPoint GLCompute %main "main" %live1 %dead1 %dead2 %live2
  5795. OpExecutionMode %main LocalSize 1 1 1
  5796. OpName %main "main"
  5797. OpName %live1 "live1"
  5798. OpName %live2 "live2"
  5799. OpName %dead1 "dead1"
  5800. OpName %dead2 "dead2"
  5801. %void = OpTypeVoid
  5802. %int = OpTypeInt 32 0
  5803. %int0 = OpConstant %int 0
  5804. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  5805. %live1 = OpVariable %ptr_ssbo_int StorageBuffer
  5806. %live2 = OpVariable %ptr_ssbo_int StorageBuffer
  5807. %dead1 = OpVariable %ptr_ssbo_int StorageBuffer
  5808. %dead2 = OpVariable %ptr_ssbo_int StorageBuffer
  5809. %void_fn = OpTypeFunction %void
  5810. %main = OpFunction %void None %void_fn
  5811. %entry = OpLabel
  5812. OpStore %live1 %int0
  5813. OpStore %live2 %int0
  5814. OpReturn
  5815. OpFunctionEnd
  5816. )";
  5817. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  5818. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  5819. }
  5820. TEST_F(AggressiveDCETest, PreserveBindings) {
  5821. const std::string spirv = R"(
  5822. ; CHECK: OpDecorate %unusedSampler DescriptorSet 0
  5823. ; CHECK: OpDecorate %unusedSampler Binding 0
  5824. OpCapability Shader
  5825. %1 = OpExtInstImport "GLSL.std.450"
  5826. OpMemoryModel Logical GLSL450
  5827. OpEntryPoint Fragment %main "main"
  5828. OpExecutionMode %main OriginUpperLeft
  5829. OpSource GLSL 430
  5830. OpName %main "main"
  5831. OpName %unusedSampler "unusedSampler"
  5832. OpDecorate %unusedSampler DescriptorSet 0
  5833. OpDecorate %unusedSampler Binding 0
  5834. %void = OpTypeVoid
  5835. %5 = OpTypeFunction %void
  5836. %float = OpTypeFloat 32
  5837. %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
  5838. %8 = OpTypeSampledImage %7
  5839. %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
  5840. %unusedSampler = OpVariable %_ptr_UniformConstant_8 UniformConstant
  5841. %main = OpFunction %void None %5
  5842. %10 = OpLabel
  5843. OpReturn
  5844. OpFunctionEnd
  5845. )";
  5846. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  5847. OptimizerOptions()->preserve_bindings_ = true;
  5848. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  5849. }
  5850. TEST_F(AggressiveDCETest, PreserveSpecConstants) {
  5851. const std::string spirv = R"(
  5852. ; CHECK: OpName %specConstant "specConstant"
  5853. ; CHECK: %specConstant = OpSpecConstant %int 0
  5854. OpCapability Shader
  5855. %1 = OpExtInstImport "GLSL.std.450"
  5856. OpMemoryModel Logical GLSL450
  5857. OpEntryPoint Fragment %main "main"
  5858. OpExecutionMode %main OriginUpperLeft
  5859. OpSource GLSL 430
  5860. OpName %main "main"
  5861. OpName %specConstant "specConstant"
  5862. OpDecorate %specConstant SpecId 0
  5863. %void = OpTypeVoid
  5864. %3 = OpTypeFunction %void
  5865. %int = OpTypeInt 32 1
  5866. %specConstant = OpSpecConstant %int 0
  5867. %main = OpFunction %void None %3
  5868. %5 = OpLabel
  5869. OpReturn
  5870. OpFunctionEnd
  5871. )";
  5872. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  5873. OptimizerOptions()->preserve_spec_constants_ = true;
  5874. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  5875. }
  5876. TEST_F(AggressiveDCETest, LiveDecorateId) {
  5877. const std::string spirv = R"(OpCapability Shader
  5878. OpMemoryModel Logical GLSL450
  5879. OpEntryPoint GLCompute %1 "main" %2
  5880. OpExecutionMode %1 LocalSize 8 1 1
  5881. OpDecorate %2 DescriptorSet 0
  5882. OpDecorate %2 Binding 0
  5883. OpDecorateId %3 UniformId %uint_2
  5884. %void = OpTypeVoid
  5885. %uint = OpTypeInt 32 0
  5886. %uint_2 = OpConstant %uint 2
  5887. %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
  5888. %2 = OpVariable %_ptr_StorageBuffer_uint StorageBuffer
  5889. %8 = OpTypeFunction %void
  5890. %1 = OpFunction %void None %8
  5891. %9 = OpLabel
  5892. %3 = OpLoad %uint %2
  5893. OpStore %2 %3
  5894. OpReturn
  5895. OpFunctionEnd
  5896. )";
  5897. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  5898. OptimizerOptions()->preserve_spec_constants_ = true;
  5899. SinglePassRunAndCheck<AggressiveDCEPass>(spirv, spirv, true);
  5900. }
  5901. TEST_F(AggressiveDCETest, LiveDecorateIdOnGroup) {
  5902. const std::string spirv = R"(OpCapability Shader
  5903. OpMemoryModel Logical GLSL450
  5904. OpEntryPoint GLCompute %1 "main" %2
  5905. OpExecutionMode %1 LocalSize 8 1 1
  5906. OpDecorate %2 DescriptorSet 0
  5907. OpDecorate %2 Binding 0
  5908. OpDecorateId %3 UniformId %uint_2
  5909. %3 = OpDecorationGroup
  5910. OpGroupDecorate %3 %5
  5911. %void = OpTypeVoid
  5912. %uint = OpTypeInt 32 0
  5913. %uint_2 = OpConstant %uint 2
  5914. %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
  5915. %2 = OpVariable %_ptr_StorageBuffer_uint StorageBuffer
  5916. %9 = OpTypeFunction %void
  5917. %1 = OpFunction %void None %9
  5918. %10 = OpLabel
  5919. %5 = OpLoad %uint %2
  5920. OpStore %2 %5
  5921. OpReturn
  5922. OpFunctionEnd
  5923. )";
  5924. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  5925. OptimizerOptions()->preserve_spec_constants_ = true;
  5926. SinglePassRunAndCheck<AggressiveDCEPass>(spirv, spirv, true);
  5927. }
  5928. TEST_F(AggressiveDCETest, NoEliminateForwardPointer) {
  5929. // clang-format off
  5930. //
  5931. // #version 450
  5932. // #extension GL_EXT_buffer_reference : enable
  5933. //
  5934. // // forward reference
  5935. // layout(buffer_reference) buffer blockType;
  5936. //
  5937. // layout(buffer_reference, std430, buffer_reference_align = 16) buffer blockType {
  5938. // int x;
  5939. // blockType next;
  5940. // };
  5941. //
  5942. // layout(std430) buffer rootBlock {
  5943. // blockType root;
  5944. // } r;
  5945. //
  5946. // void main()
  5947. // {
  5948. // blockType b = r.root;
  5949. // b = b.next;
  5950. // b.x = 531;
  5951. // }
  5952. //
  5953. // clang-format on
  5954. const std::string predefs1 =
  5955. R"(OpCapability Shader
  5956. OpCapability PhysicalStorageBufferAddresses
  5957. OpExtension "SPV_EXT_physical_storage_buffer"
  5958. OpExtension "SPV_KHR_storage_buffer_storage_class"
  5959. %1 = OpExtInstImport "GLSL.std.450"
  5960. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  5961. OpEntryPoint GLCompute %main "main"
  5962. OpExecutionMode %main LocalSize 1 1 1
  5963. OpSource GLSL 450
  5964. OpSourceExtension "GL_EXT_buffer_reference"
  5965. )";
  5966. const std::string names_before =
  5967. R"(OpName %main "main"
  5968. OpName %blockType "blockType"
  5969. OpMemberName %blockType 0 "x"
  5970. OpMemberName %blockType 1 "next"
  5971. OpName %b "b"
  5972. OpName %rootBlock "rootBlock"
  5973. OpMemberName %rootBlock 0 "root"
  5974. OpName %r "r"
  5975. OpMemberDecorate %blockType 0 Offset 0
  5976. OpMemberDecorate %blockType 1 Offset 8
  5977. OpDecorate %blockType Block
  5978. OpDecorate %b AliasedPointer
  5979. OpMemberDecorate %rootBlock 0 Offset 0
  5980. OpDecorate %rootBlock Block
  5981. OpDecorate %r DescriptorSet 0
  5982. OpDecorate %r Binding 0
  5983. )";
  5984. const std::string names_after =
  5985. R"(OpName %main "main"
  5986. OpName %blockType "blockType"
  5987. OpMemberName %blockType 0 "x"
  5988. OpMemberName %blockType 1 "next"
  5989. OpName %rootBlock "rootBlock"
  5990. OpMemberName %rootBlock 0 "root"
  5991. OpName %r "r"
  5992. OpMemberDecorate %blockType 0 Offset 0
  5993. OpMemberDecorate %blockType 1 Offset 8
  5994. OpDecorate %blockType Block
  5995. OpMemberDecorate %rootBlock 0 Offset 0
  5996. OpDecorate %rootBlock Block
  5997. OpDecorate %r DescriptorSet 0
  5998. OpDecorate %r Binding 0
  5999. )";
  6000. const std::string predefs2_before =
  6001. R"(%void = OpTypeVoid
  6002. %3 = OpTypeFunction %void
  6003. OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer
  6004. %int = OpTypeInt 32 1
  6005. %blockType = OpTypeStruct %int %_ptr_PhysicalStorageBuffer_blockType
  6006. %_ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %blockType
  6007. %_ptr_Function__ptr_PhysicalStorageBuffer_blockType = OpTypePointer Function %_ptr_PhysicalStorageBuffer_blockType
  6008. %rootBlock = OpTypeStruct %_ptr_PhysicalStorageBuffer_blockType
  6009. %_ptr_StorageBuffer_rootBlock = OpTypePointer StorageBuffer %rootBlock
  6010. %r = OpVariable %_ptr_StorageBuffer_rootBlock StorageBuffer
  6011. %int_0 = OpConstant %int 0
  6012. %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBuffer_blockType
  6013. %int_1 = OpConstant %int 1
  6014. %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_blockType
  6015. %int_531 = OpConstant %int 531
  6016. %_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
  6017. )";
  6018. const std::string predefs2_after =
  6019. R"(%void = OpTypeVoid
  6020. %8 = OpTypeFunction %void
  6021. OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer
  6022. %int = OpTypeInt 32 1
  6023. %blockType = OpTypeStruct %int %_ptr_PhysicalStorageBuffer_blockType
  6024. %_ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %blockType
  6025. %rootBlock = OpTypeStruct %_ptr_PhysicalStorageBuffer_blockType
  6026. %_ptr_StorageBuffer_rootBlock = OpTypePointer StorageBuffer %rootBlock
  6027. %r = OpVariable %_ptr_StorageBuffer_rootBlock StorageBuffer
  6028. %int_0 = OpConstant %int 0
  6029. %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBuffer_blockType
  6030. %int_1 = OpConstant %int 1
  6031. %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_blockType
  6032. %int_531 = OpConstant %int 531
  6033. %_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
  6034. )";
  6035. const std::string func_before =
  6036. R"(%main = OpFunction %void None %3
  6037. %5 = OpLabel
  6038. %b = OpVariable %_ptr_Function__ptr_PhysicalStorageBuffer_blockType Function
  6039. %16 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType %r %int_0
  6040. %17 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %16
  6041. %21 = OpAccessChain %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType %17 %int_1
  6042. %22 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8
  6043. OpStore %b %22
  6044. %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %22 %int_0
  6045. OpStore %26 %int_531 Aligned 16
  6046. OpReturn
  6047. OpFunctionEnd
  6048. )";
  6049. const std::string func_after =
  6050. R"(%main = OpFunction %void None %8
  6051. %19 = OpLabel
  6052. %20 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType %r %int_0
  6053. %21 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %20
  6054. %22 = OpAccessChain %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType %21 %int_1
  6055. %23 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %22 Aligned 8
  6056. %24 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %23 %int_0
  6057. OpStore %24 %int_531 Aligned 16
  6058. OpReturn
  6059. OpFunctionEnd
  6060. )";
  6061. SinglePassRunAndCheck<AggressiveDCEPass>(
  6062. predefs1 + names_before + predefs2_before + func_before,
  6063. predefs1 + names_after + predefs2_after + func_after, true, true);
  6064. }
  6065. TEST_F(AggressiveDCETest, MultipleFunctionProcessIndependently) {
  6066. const std::string spirv = R"(
  6067. OpCapability Shader
  6068. OpMemoryModel Logical GLSL450
  6069. OpEntryPoint GLCompute %entryHistogram "entryHistogram" %gl_GlobalInvocationID %gl_LocalInvocationIndex
  6070. OpEntryPoint GLCompute %entryAverage "entryAverage" %gl_GlobalInvocationID %gl_LocalInvocationIndex
  6071. OpExecutionMode %entryHistogram LocalSize 16 16 1
  6072. OpExecutionMode %entryAverage LocalSize 256 1 1
  6073. OpSource HLSL 640
  6074. OpName %type_RWStructuredBuffer_uint "type.RWStructuredBuffer.uint"
  6075. OpName %uHistogram "uHistogram"
  6076. OpName %type_ACSBuffer_counter "type.ACSBuffer.counter"
  6077. OpMemberName %type_ACSBuffer_counter 0 "counter"
  6078. OpName %counter_var_uHistogram "counter.var.uHistogram"
  6079. OpName %sharedHistogram "sharedHistogram"
  6080. OpName %entryHistogram "entryHistogram"
  6081. OpName %param_var_id "param.var.id"
  6082. OpName %param_var_idx "param.var.idx"
  6083. OpName %entryAverage "entryAverage"
  6084. OpName %param_var_id_0 "param.var.id"
  6085. OpName %param_var_idx_0 "param.var.idx"
  6086. OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
  6087. OpDecorate %gl_LocalInvocationIndex BuiltIn LocalInvocationIndex
  6088. OpDecorate %uHistogram DescriptorSet 0
  6089. OpDecorate %uHistogram Binding 0
  6090. OpDecorate %counter_var_uHistogram DescriptorSet 0
  6091. OpDecorate %counter_var_uHistogram Binding 1
  6092. OpDecorate %_runtimearr_uint ArrayStride 4
  6093. OpMemberDecorate %type_RWStructuredBuffer_uint 0 Offset 0
  6094. OpDecorate %type_RWStructuredBuffer_uint BufferBlock
  6095. OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0
  6096. OpDecorate %type_ACSBuffer_counter BufferBlock
  6097. %uint = OpTypeInt 32 0
  6098. %uint_0 = OpConstant %uint 0
  6099. %uint_1 = OpConstant %uint 1
  6100. %uint_2 = OpConstant %uint 2
  6101. %uint_4 = OpConstant %uint 4
  6102. %uint_8 = OpConstant %uint 8
  6103. %uint_16 = OpConstant %uint 16
  6104. %uint_32 = OpConstant %uint 32
  6105. %uint_64 = OpConstant %uint 64
  6106. %uint_128 = OpConstant %uint 128
  6107. %uint_256 = OpConstant %uint 256
  6108. %uint_512 = OpConstant %uint 512
  6109. %uint_254 = OpConstant %uint 254
  6110. %uint_255 = OpConstant %uint 255
  6111. %int = OpTypeInt 32 1
  6112. %int_0 = OpConstant %int 0
  6113. %_runtimearr_uint = OpTypeRuntimeArray %uint
  6114. %type_RWStructuredBuffer_uint = OpTypeStruct %_runtimearr_uint
  6115. %_ptr_Uniform_type_RWStructuredBuffer_uint = OpTypePointer Uniform %type_RWStructuredBuffer_uint
  6116. %type_ACSBuffer_counter = OpTypeStruct %int
  6117. %_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter
  6118. %_arr_uint_uint_256 = OpTypeArray %uint %uint_256
  6119. %_ptr_Workgroup__arr_uint_uint_256 = OpTypePointer Workgroup %_arr_uint_uint_256
  6120. %v3uint = OpTypeVector %uint 3
  6121. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  6122. %_ptr_Input_uint = OpTypePointer Input %uint
  6123. %void = OpTypeVoid
  6124. %49 = OpTypeFunction %void
  6125. %_ptr_Function_v3uint = OpTypePointer Function %v3uint
  6126. %_ptr_Function_uint = OpTypePointer Function %uint
  6127. %52 = OpTypeFunction %void %_ptr_Function_v3uint %_ptr_Function_uint
  6128. %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  6129. %uint_264 = OpConstant %uint 264
  6130. %bool = OpTypeBool
  6131. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  6132. %uHistogram = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_uint Uniform
  6133. %counter_var_uHistogram = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
  6134. %sharedHistogram = OpVariable %_ptr_Workgroup__arr_uint_uint_256 Workgroup
  6135. %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
  6136. %gl_LocalInvocationIndex = OpVariable %_ptr_Input_uint Input
  6137. %entryHistogram = OpFunction %void None %49
  6138. %57 = OpLabel
  6139. %param_var_id = OpVariable %_ptr_Function_v3uint Function
  6140. %param_var_idx = OpVariable %_ptr_Function_uint Function
  6141. %58 = OpLoad %v3uint %gl_GlobalInvocationID
  6142. %59 = OpLoad %uint %gl_LocalInvocationIndex
  6143. %79 = OpAccessChain %_ptr_Workgroup_uint %sharedHistogram %int_0
  6144. %80 = OpAtomicIAdd %uint %79 %uint_1 %uint_0 %uint_1
  6145. OpReturn
  6146. OpFunctionEnd
  6147. %entryAverage = OpFunction %void None %49
  6148. %63 = OpLabel
  6149. %param_var_id_0 = OpVariable %_ptr_Function_v3uint Function
  6150. %param_var_idx_0 = OpVariable %_ptr_Function_uint Function
  6151. %64 = OpLoad %v3uint %gl_GlobalInvocationID
  6152. %65 = OpLoad %uint %gl_LocalInvocationIndex
  6153. OpStore %param_var_idx_0 %65
  6154. %83 = OpAccessChain %_ptr_Workgroup_uint %sharedHistogram %65
  6155. OpStore %83 %uint_0
  6156. ; CHECK: [[ieq:%\w+]] = OpIEqual
  6157. ; CHECK-NEXT: OpSelectionMerge [[merge:%\w+]]
  6158. ; CHECK-NEXT: OpBranchConditional [[ieq]] [[not_elim:%\w+]] [[merge]]
  6159. ; CHECK-NEXT: [[not_elim]] = OpLabel
  6160. ; CHECK: [[merge]] = OpLabel
  6161. OpControlBarrier %uint_2 %uint_2 %uint_264
  6162. %85 = OpIEqual %bool %65 %uint_0
  6163. OpSelectionMerge %89 None
  6164. OpBranchConditional %85 %86 %89
  6165. %86 = OpLabel
  6166. %88 = OpAccessChain %_ptr_Workgroup_uint %sharedHistogram %65
  6167. OpStore %88 %uint_1
  6168. OpBranch %89
  6169. %89 = OpLabel
  6170. OpControlBarrier %uint_2 %uint_2 %uint_264
  6171. %91 = OpAccessChain %_ptr_Workgroup_uint %sharedHistogram %65
  6172. %92 = OpLoad %uint %91
  6173. %94 = OpAccessChain %_ptr_Uniform_uint %uHistogram %int_0 %65
  6174. OpStore %94 %92
  6175. OpReturn
  6176. OpFunctionEnd
  6177. )";
  6178. SetTargetEnv(SPV_ENV_UNIVERSAL_1_3);
  6179. SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
  6180. }
  6181. TEST_F(AggressiveDCETest, DebugInfoKeepInFunctionElimStoreVar) {
  6182. // Verify that dead local variable tc and store eliminated but all
  6183. // in-function debuginfo kept.
  6184. //
  6185. // The SPIR-V has been inlined and local single store eliminated
  6186. //
  6187. // Texture2D g_tColor;
  6188. // SamplerState g_sAniso;
  6189. //
  6190. // struct PS_INPUT {
  6191. // float2 vTextureCoords : TEXCOORD2;
  6192. // };
  6193. //
  6194. // struct PS_OUTPUT {
  6195. // float4 vColor : SV_Target0;
  6196. // };
  6197. //
  6198. // PS_OUTPUT MainPs(PS_INPUT i) {
  6199. // PS_OUTPUT ps_output;
  6200. // float2 tc = i.vTextureCoords.xy;
  6201. // ps_output.vColor = g_tColor.Sample(g_sAniso, tc);
  6202. // return ps_output;
  6203. // }
  6204. const std::string text = R"(
  6205. OpCapability Shader
  6206. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  6207. OpMemoryModel Logical GLSL450
  6208. OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_sAniso %in_var_TEXCOORD2 %out_var_SV_Target0
  6209. OpExecutionMode %MainPs OriginUpperLeft
  6210. %7 = OpString "foo.frag"
  6211. %8 = OpString "PS_OUTPUT"
  6212. %9 = OpString "float"
  6213. %10 = OpString "vColor"
  6214. %11 = OpString "PS_INPUT"
  6215. %12 = OpString "vTextureCoords"
  6216. %13 = OpString "@type.2d.image"
  6217. %14 = OpString "type.2d.image"
  6218. %15 = OpString "Texture2D.TemplateParam"
  6219. %16 = OpString "src.MainPs"
  6220. %17 = OpString "tc"
  6221. %18 = OpString "ps_output"
  6222. %19 = OpString "i"
  6223. %20 = OpString "@type.sampler"
  6224. %21 = OpString "type.sampler"
  6225. %22 = OpString "g_sAniso"
  6226. %23 = OpString "g_tColor"
  6227. OpName %type_2d_image "type.2d.image"
  6228. OpName %g_tColor "g_tColor"
  6229. OpName %type_sampler "type.sampler"
  6230. OpName %g_sAniso "g_sAniso"
  6231. OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
  6232. OpName %out_var_SV_Target0 "out.var.SV_Target0"
  6233. OpName %MainPs "MainPs"
  6234. OpName %PS_INPUT "PS_INPUT"
  6235. OpMemberName %PS_INPUT 0 "vTextureCoords"
  6236. OpName %param_var_i "param.var.i"
  6237. OpName %PS_OUTPUT "PS_OUTPUT"
  6238. OpMemberName %PS_OUTPUT 0 "vColor"
  6239. OpName %type_sampled_image "type.sampled.image"
  6240. OpDecorate %in_var_TEXCOORD2 Location 0
  6241. OpDecorate %out_var_SV_Target0 Location 0
  6242. OpDecorate %g_tColor DescriptorSet 0
  6243. OpDecorate %g_tColor Binding 0
  6244. OpDecorate %g_sAniso DescriptorSet 0
  6245. OpDecorate %g_sAniso Binding 1
  6246. %int = OpTypeInt 32 1
  6247. %int_0 = OpConstant %int 0
  6248. %uint = OpTypeInt 32 0
  6249. %uint_32 = OpConstant %uint 32
  6250. %float = OpTypeFloat 32
  6251. %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
  6252. %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
  6253. %type_sampler = OpTypeSampler
  6254. %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
  6255. %v2float = OpTypeVector %float 2
  6256. %_ptr_Input_v2float = OpTypePointer Input %v2float
  6257. %v4float = OpTypeVector %float 4
  6258. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6259. %void = OpTypeVoid
  6260. %uint_128 = OpConstant %uint 128
  6261. %uint_0 = OpConstant %uint 0
  6262. %uint_64 = OpConstant %uint 64
  6263. %45 = OpTypeFunction %void
  6264. %PS_INPUT = OpTypeStruct %v2float
  6265. %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
  6266. %PS_OUTPUT = OpTypeStruct %v4float
  6267. %47 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
  6268. %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
  6269. %_ptr_Function_v2float = OpTypePointer Function %v2float
  6270. %type_sampled_image = OpTypeSampledImage %type_2d_image
  6271. %_ptr_Function_v4float = OpTypePointer Function %v4float
  6272. %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
  6273. %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
  6274. %in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
  6275. %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
  6276. %51 = OpExtInst %void %1 DebugInfoNone
  6277. %52 = OpExtInst %void %1 DebugExpression
  6278. %53 = OpExtInst %void %1 DebugOperation Deref
  6279. %54 = OpExtInst %void %1 DebugExpression %53
  6280. %55 = OpExtInst %void %1 DebugSource %7
  6281. %56 = OpExtInst %void %1 DebugCompilationUnit 1 4 %55 HLSL
  6282. %57 = OpExtInst %void %1 DebugTypeComposite %8 Structure %55 10 1 %56 %8 %uint_128 FlagIsProtected|FlagIsPrivate %58
  6283. %59 = OpExtInst %void %1 DebugTypeBasic %9 %uint_32 Float
  6284. %60 = OpExtInst %void %1 DebugTypeVector %59 4
  6285. %58 = OpExtInst %void %1 DebugTypeMember %10 %60 %55 12 5 %57 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
  6286. %61 = OpExtInst %void %1 DebugTypeComposite %11 Structure %55 5 1 %56 %11 %uint_64 FlagIsProtected|FlagIsPrivate %62
  6287. %63 = OpExtInst %void %1 DebugTypeVector %59 2
  6288. %62 = OpExtInst %void %1 DebugTypeMember %12 %63 %55 7 5 %61 %uint_0 %uint_64 FlagIsProtected|FlagIsPrivate
  6289. %64 = OpExtInst %void %1 DebugTypeComposite %13 Class %55 0 0 %56 %14 %51 FlagIsProtected|FlagIsPrivate
  6290. %65 = OpExtInst %void %1 DebugTypeTemplateParameter %15 %59 %51 %55 0 0
  6291. %66 = OpExtInst %void %1 DebugTypeTemplate %64 %65
  6292. %67 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %57 %61
  6293. %68 = OpExtInst %void %1 DebugFunction %16 %67 %55 15 1 %56 %16 FlagIsProtected|FlagIsPrivate 16 %51
  6294. %69 = OpExtInst %void %1 DebugLexicalBlock %55 16 1 %68
  6295. %70 = OpExtInst %void %1 DebugLocalVariable %17 %63 %55 19 12 %69 FlagIsLocal
  6296. %71 = OpExtInst %void %1 DebugLocalVariable %18 %57 %55 17 15 %69 FlagIsLocal
  6297. %72 = OpExtInst %void %1 DebugLocalVariable %19 %61 %55 15 29 %68 FlagIsLocal 1
  6298. %73 = OpExtInst %void %1 DebugTypeComposite %20 Structure %55 0 0 %56 %21 %51 FlagIsProtected|FlagIsPrivate
  6299. %74 = OpExtInst %void %1 DebugGlobalVariable %22 %73 %55 3 14 %56 %22 %g_sAniso FlagIsDefinition
  6300. %75 = OpExtInst %void %1 DebugGlobalVariable %23 %64 %55 1 11 %56 %23 %g_tColor FlagIsDefinition
  6301. %MainPs = OpFunction %void None %45
  6302. %76 = OpLabel
  6303. %107 = OpExtInst %void %1 DebugScope %69
  6304. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugScope %69
  6305. %78 = OpVariable %_ptr_Function_PS_OUTPUT Function
  6306. %79 = OpVariable %_ptr_Function_v2float Function
  6307. %108 = OpExtInst %void %1 DebugNoScope
  6308. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugNoScope
  6309. %81 = OpVariable %_ptr_Function_PS_OUTPUT Function
  6310. %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
  6311. %82 = OpLoad %v2float %in_var_TEXCOORD2
  6312. %83 = OpCompositeConstruct %PS_INPUT %82
  6313. OpStore %param_var_i %83
  6314. %109 = OpExtInst %void %1 DebugScope %68
  6315. %85 = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
  6316. %110 = OpExtInst %void %1 DebugScope %69
  6317. %87 = OpExtInst %void %1 DebugDeclare %71 %78 %52
  6318. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugScope %68
  6319. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
  6320. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugScope %69
  6321. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugDeclare %71 %78 %52
  6322. OpLine %7 19 17
  6323. %88 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
  6324. %89 = OpLoad %v2float %88
  6325. OpLine %7 19 12
  6326. OpStore %79 %89
  6327. ;CHECK-NOT: OpStore %79 %89
  6328. OpLine %7 19 12
  6329. %106 = OpExtInst %void %1 DebugValue %70 %89 %52
  6330. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugValue %70 %89 %52
  6331. OpLine %7 20 26
  6332. %91 = OpLoad %type_2d_image %g_tColor
  6333. OpLine %7 20 46
  6334. %92 = OpLoad %type_sampler %g_sAniso
  6335. OpLine %7 20 26
  6336. %94 = OpSampledImage %type_sampled_image %91 %92
  6337. %95 = OpImageSampleImplicitLod %v4float %94 %89 None
  6338. OpLine %7 20 5
  6339. %96 = OpAccessChain %_ptr_Function_v4float %78 %int_0
  6340. OpStore %96 %95
  6341. OpLine %7 21 12
  6342. %97 = OpLoad %PS_OUTPUT %78
  6343. OpLine %7 21 5
  6344. OpStore %81 %97
  6345. %111 = OpExtInst %void %1 DebugNoScope
  6346. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugNoScope
  6347. %100 = OpCompositeExtract %v4float %97 0
  6348. OpStore %out_var_SV_Target0 %100
  6349. OpReturn
  6350. OpFunctionEnd
  6351. )";
  6352. SetTargetEnv(SPV_ENV_VULKAN_1_2);
  6353. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  6354. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  6355. }
  6356. TEST_F(AggressiveDCETest, ShaderDebugInfoKeepInFunctionElimStoreVar) {
  6357. // Verify that dead local variable tc and store eliminated but all
  6358. // in-function NonSemantic Shader debuginfo kept.
  6359. const std::string text = R"(
  6360. OpCapability Shader
  6361. OpExtension "SPV_KHR_non_semantic_info"
  6362. %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
  6363. OpMemoryModel Logical GLSL450
  6364. OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_sAniso %in_var_TEXCOORD2 %out_var_SV_Target0
  6365. OpExecutionMode %MainPs OriginUpperLeft
  6366. %7 = OpString "foo.frag"
  6367. %8 = OpString "PS_OUTPUT"
  6368. %9 = OpString "float"
  6369. %10 = OpString "vColor"
  6370. %11 = OpString "PS_INPUT"
  6371. %12 = OpString "vTextureCoords"
  6372. %13 = OpString "@type.2d.image"
  6373. %14 = OpString "type.2d.image"
  6374. %15 = OpString "Texture2D.TemplateParam"
  6375. %16 = OpString "src.MainPs"
  6376. %17 = OpString "tc"
  6377. %18 = OpString "ps_output"
  6378. %19 = OpString "i"
  6379. %20 = OpString "@type.sampler"
  6380. %21 = OpString "type.sampler"
  6381. %22 = OpString "g_sAniso"
  6382. %23 = OpString "g_tColor"
  6383. OpName %type_2d_image "type.2d.image"
  6384. OpName %g_tColor "g_tColor"
  6385. OpName %type_sampler "type.sampler"
  6386. OpName %g_sAniso "g_sAniso"
  6387. OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
  6388. OpName %out_var_SV_Target0 "out.var.SV_Target0"
  6389. OpName %MainPs "MainPs"
  6390. OpName %PS_INPUT "PS_INPUT"
  6391. OpMemberName %PS_INPUT 0 "vTextureCoords"
  6392. OpName %param_var_i "param.var.i"
  6393. OpName %PS_OUTPUT "PS_OUTPUT"
  6394. OpMemberName %PS_OUTPUT 0 "vColor"
  6395. OpName %type_sampled_image "type.sampled.image"
  6396. OpDecorate %in_var_TEXCOORD2 Location 0
  6397. OpDecorate %out_var_SV_Target0 Location 0
  6398. OpDecorate %g_tColor DescriptorSet 0
  6399. OpDecorate %g_tColor Binding 0
  6400. OpDecorate %g_sAniso DescriptorSet 0
  6401. OpDecorate %g_sAniso Binding 1
  6402. %int = OpTypeInt 32 1
  6403. %int_0 = OpConstant %int 0
  6404. %uint = OpTypeInt 32 0
  6405. %uint_32 = OpConstant %uint 32
  6406. %float = OpTypeFloat 32
  6407. %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
  6408. %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
  6409. %type_sampler = OpTypeSampler
  6410. %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
  6411. %v2float = OpTypeVector %float 2
  6412. %_ptr_Input_v2float = OpTypePointer Input %v2float
  6413. %v4float = OpTypeVector %float 4
  6414. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6415. %void = OpTypeVoid
  6416. %uint_128 = OpConstant %uint 128
  6417. %uint_0 = OpConstant %uint 0
  6418. %uint_1 = OpConstant %uint 1
  6419. %uint_2 = OpConstant %uint 2
  6420. %uint_3 = OpConstant %uint 3
  6421. %uint_4 = OpConstant %uint 4
  6422. %uint_5 = OpConstant %uint 5
  6423. %uint_7 = OpConstant %uint 7
  6424. %uint_8 = OpConstant %uint 8
  6425. %uint_10 = OpConstant %uint 10
  6426. %uint_11 = OpConstant %uint 11
  6427. %uint_12 = OpConstant %uint 12
  6428. %uint_14 = OpConstant %uint 14
  6429. %uint_15 = OpConstant %uint 15
  6430. %uint_16 = OpConstant %uint 16
  6431. %uint_17 = OpConstant %uint 17
  6432. %uint_19 = OpConstant %uint 19
  6433. %uint_20 = OpConstant %uint 20
  6434. %uint_21 = OpConstant %uint 21
  6435. %uint_25 = OpConstant %uint 25
  6436. %uint_29 = OpConstant %uint 29
  6437. %uint_30 = OpConstant %uint 30
  6438. %uint_35 = OpConstant %uint 35
  6439. %uint_41 = OpConstant %uint 41
  6440. %uint_48 = OpConstant %uint 48
  6441. %uint_53 = OpConstant %uint 53
  6442. %uint_64 = OpConstant %uint 64
  6443. %45 = OpTypeFunction %void
  6444. %PS_INPUT = OpTypeStruct %v2float
  6445. %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
  6446. %PS_OUTPUT = OpTypeStruct %v4float
  6447. %47 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
  6448. %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
  6449. %_ptr_Function_v2float = OpTypePointer Function %v2float
  6450. %type_sampled_image = OpTypeSampledImage %type_2d_image
  6451. %_ptr_Function_v4float = OpTypePointer Function %v4float
  6452. %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
  6453. %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
  6454. %in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
  6455. %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
  6456. %51 = OpExtInst %void %1 DebugInfoNone
  6457. %52 = OpExtInst %void %1 DebugExpression
  6458. %53 = OpExtInst %void %1 DebugOperation %uint_0
  6459. %54 = OpExtInst %void %1 DebugExpression %53
  6460. %55 = OpExtInst %void %1 DebugSource %7
  6461. %56 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %55 %uint_5
  6462. %59 = OpExtInst %void %1 DebugTypeBasic %9 %uint_32 %uint_3 %uint_0
  6463. %60 = OpExtInst %void %1 DebugTypeVector %59 %uint_4
  6464. %58 = OpExtInst %void %1 DebugTypeMember %10 %60 %55 %uint_12 %uint_5 %uint_0 %uint_128 %uint_3
  6465. %57 = OpExtInst %void %1 DebugTypeComposite %8 %uint_1 %55 %uint_10 %uint_1 %56 %8 %uint_128 %uint_3 %58
  6466. %63 = OpExtInst %void %1 DebugTypeVector %59 %uint_2
  6467. %62 = OpExtInst %void %1 DebugTypeMember %12 %63 %55 %uint_7 %uint_5 %uint_0 %uint_64 %uint_3
  6468. %61 = OpExtInst %void %1 DebugTypeComposite %11 %uint_1 %55 %uint_5 %uint_1 %56 %11 %uint_64 %uint_3 %62
  6469. %64 = OpExtInst %void %1 DebugTypeComposite %13 %uint_0 %55 %uint_0 %uint_0 %56 %14 %51 %uint_3
  6470. %67 = OpExtInst %void %1 DebugTypeFunction %uint_3 %57 %61
  6471. %68 = OpExtInst %void %1 DebugFunction %16 %67 %55 %uint_15 %uint_1 %56 %16 %uint_3 %uint_16
  6472. %69 = OpExtInst %void %1 DebugLexicalBlock %55 %uint_16 %uint_1 %68
  6473. %70 = OpExtInst %void %1 DebugLocalVariable %17 %63 %55 %uint_19 %uint_12 %69 %uint_4
  6474. %71 = OpExtInst %void %1 DebugLocalVariable %18 %57 %55 %uint_17 %uint_15 %69 %uint_4
  6475. %72 = OpExtInst %void %1 DebugLocalVariable %19 %61 %55 %uint_15 %uint_29 %68 %uint_4 %uint_1
  6476. %73 = OpExtInst %void %1 DebugTypeComposite %20 %uint_1 %55 %uint_0 %uint_0 %56 %21 %51 %uint_3
  6477. %74 = OpExtInst %void %1 DebugGlobalVariable %22 %73 %55 %uint_3 %uint_14 %56 %22 %g_sAniso %uint_8
  6478. %75 = OpExtInst %void %1 DebugGlobalVariable %23 %64 %55 %uint_1 %uint_11 %56 %23 %g_tColor %uint_8
  6479. %MainPs = OpFunction %void None %45
  6480. %76 = OpLabel
  6481. %78 = OpVariable %_ptr_Function_PS_OUTPUT Function
  6482. %79 = OpVariable %_ptr_Function_v2float Function
  6483. %81 = OpVariable %_ptr_Function_PS_OUTPUT Function
  6484. %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
  6485. %82 = OpLoad %v2float %in_var_TEXCOORD2
  6486. %83 = OpCompositeConstruct %PS_INPUT %82
  6487. OpStore %param_var_i %83
  6488. %112 = OpExtInst %void %1 DebugFunctionDefinition %68 %MainPs
  6489. %109 = OpExtInst %void %1 DebugScope %68
  6490. %85 = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
  6491. %110 = OpExtInst %void %1 DebugScope %69
  6492. %87 = OpExtInst %void %1 DebugDeclare %71 %78 %52
  6493. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugFunctionDefinition %68 %MainPs
  6494. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugScope %68
  6495. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
  6496. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugScope %69
  6497. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugDeclare %71 %78 %52
  6498. %300 = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_17 %uint_30
  6499. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_17 %uint_30
  6500. %88 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
  6501. %89 = OpLoad %v2float %88
  6502. %301 = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_12 %uint_35
  6503. OpStore %79 %89
  6504. ;CHECK-NOT: OpStore %79 %89
  6505. %302 = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_12 %uint_35
  6506. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_12 %uint_35
  6507. %106 = OpExtInst %void %1 DebugValue %70 %89 %52
  6508. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugValue %70 %89 %52
  6509. %303 = OpExtInst %void %1 DebugLine %55 %uint_20 %uint_20 %uint_25 %uint_32
  6510. %91 = OpLoad %type_2d_image %g_tColor
  6511. %304 = OpExtInst %void %1 DebugLine %55 %uint_20 %uint_20 %uint_41 %uint_48
  6512. %92 = OpLoad %type_sampler %g_sAniso
  6513. %305 = OpExtInst %void %1 DebugLine %55 %uint_20 %uint_20 %uint_25 %uint_53
  6514. %94 = OpSampledImage %type_sampled_image %91 %92
  6515. %95 = OpImageSampleImplicitLod %v4float %94 %89 None
  6516. %306 = OpExtInst %void %1 DebugLine %55 %uint_20 %uint_20 %uint_5 %uint_53
  6517. %96 = OpAccessChain %_ptr_Function_v4float %78 %int_0
  6518. OpStore %96 %95
  6519. %307 = OpExtInst %void %1 DebugLine %55 %uint_21 %uint_21 %uint_12 %uint_20
  6520. %97 = OpLoad %PS_OUTPUT %78
  6521. %308 = OpExtInst %void %1 DebugLine %55 %uint_21 %uint_21 %uint_5 %uint_20
  6522. OpStore %81 %97
  6523. %309 = OpExtInst %void %1 DebugNoLine
  6524. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugNoLine
  6525. %111 = OpExtInst %void %1 DebugNoScope
  6526. ;CHECK: {{%\w+}} = OpExtInst %void %1 DebugNoScope
  6527. %100 = OpCompositeExtract %v4float %97 0
  6528. OpStore %out_var_SV_Target0 %100
  6529. OpReturn
  6530. OpFunctionEnd
  6531. )";
  6532. SetTargetEnv(SPV_ENV_VULKAN_1_2);
  6533. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  6534. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  6535. }
  6536. TEST_F(AggressiveDCETest, ShaderDebugInfoGlobalDCE) {
  6537. // Verify that DebugGlobalVariable for eliminated private variable has
  6538. // variable operand replaced with DebugInfoNone.
  6539. const std::string text = R"(OpCapability Shader
  6540. OpExtension "SPV_KHR_non_semantic_info"
  6541. %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
  6542. OpMemoryModel Logical GLSL450
  6543. OpEntryPoint Fragment %MainPs "MainPs" %out_var_SV_Target0 %a
  6544. OpExecutionMode %MainPs OriginUpperLeft
  6545. %5 = OpString "source2.hlsl"
  6546. %24 = OpString "float"
  6547. %29 = OpString "vColor"
  6548. %33 = OpString "PS_OUTPUT"
  6549. %37 = OpString "MainPs"
  6550. %38 = OpString ""
  6551. %42 = OpString "ps_output"
  6552. %46 = OpString "a"
  6553. OpName %a "a"
  6554. OpName %out_var_SV_Target0 "out.var.SV_Target0"
  6555. OpName %MainPs "MainPs"
  6556. OpName %PS_OUTPUT "PS_OUTPUT"
  6557. OpMemberName %PS_OUTPUT 0 "vColor"
  6558. OpDecorate %out_var_SV_Target0 Location 0
  6559. %float = OpTypeFloat 32
  6560. %v4float = OpTypeVector %float 4
  6561. %8 = OpConstantNull %v4float
  6562. %float_0 = OpConstant %float 0
  6563. %10 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  6564. %int = OpTypeInt 32 1
  6565. %int_0 = OpConstant %int 0
  6566. %uint = OpTypeInt 32 0
  6567. %uint_32 = OpConstant %uint 32
  6568. %_ptr_Private_v4float = OpTypePointer Private %v4float
  6569. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6570. %void = OpTypeVoid
  6571. %uint_1 = OpConstant %uint 1
  6572. %uint_4 = OpConstant %uint 4
  6573. %uint_5 = OpConstant %uint 5
  6574. %uint_3 = OpConstant %uint 3
  6575. %uint_0 = OpConstant %uint 0
  6576. %uint_128 = OpConstant %uint 128
  6577. %uint_12 = OpConstant %uint 12
  6578. %uint_8 = OpConstant %uint 8
  6579. %uint_9 = OpConstant %uint 9
  6580. %uint_10 = OpConstant %uint 10
  6581. %uint_15 = OpConstant %uint 15
  6582. %48 = OpTypeFunction %void
  6583. %PS_OUTPUT = OpTypeStruct %v4float
  6584. %54 = OpTypeFunction %PS_OUTPUT
  6585. %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
  6586. %_ptr_Function_v4float = OpTypePointer Function %v4float
  6587. %a = OpVariable %_ptr_Private_v4float Private
  6588. ;CHECK-NOT: %a = OpVariable %_ptr_Private_v4float Private
  6589. %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
  6590. ;CHECK: [[dbg_none:%\w+]] = OpExtInst %void %1 DebugInfoNone
  6591. %18 = OpExtInst %void %1 DebugExpression
  6592. %19 = OpExtInst %void %1 DebugSource %5
  6593. %20 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %19 %uint_5
  6594. %25 = OpExtInst %void %1 DebugTypeBasic %24 %uint_32 %uint_3 %uint_0
  6595. %28 = OpExtInst %void %1 DebugTypeVector %25 %uint_4
  6596. %31 = OpExtInst %void %1 DebugTypeMember %29 %28 %19 %uint_5 %uint_12 %uint_0 %uint_128 %uint_3
  6597. %34 = OpExtInst %void %1 DebugTypeComposite %33 %uint_1 %19 %uint_3 %uint_8 %20 %33 %uint_128 %uint_3 %31
  6598. %36 = OpExtInst %void %1 DebugTypeFunction %uint_3 %34
  6599. %39 = OpExtInst %void %1 DebugFunction %37 %36 %19 %uint_8 %uint_1 %20 %38 %uint_3 %uint_9
  6600. %41 = OpExtInst %void %1 DebugLexicalBlock %19 %uint_9 %uint_1 %39
  6601. %43 = OpExtInst %void %1 DebugLocalVariable %42 %34 %19 %uint_10 %uint_15 %41 %uint_4
  6602. %47 = OpExtInst %void %1 DebugGlobalVariable %46 %28 %19 %uint_1 %uint_15 %20 %46 %a %uint_8
  6603. ;CHECK: %47 = OpExtInst %void %1 DebugGlobalVariable %46 %28 %19 %uint_1 %uint_15 %20 %46 [[dbg_none]] %uint_8
  6604. %MainPs = OpFunction %void None %48
  6605. %49 = OpLabel
  6606. %65 = OpVariable %_ptr_Function_PS_OUTPUT Function
  6607. %66 = OpVariable %_ptr_Function_PS_OUTPUT Function
  6608. OpStore %a %8
  6609. %72 = OpExtInst %void %1 DebugScope %41
  6610. %69 = OpExtInst %void %1 DebugDeclare %43 %65 %18
  6611. OpLine %5 11 5
  6612. %70 = OpAccessChain %_ptr_Function_v4float %65 %int_0
  6613. OpStore %70 %10
  6614. OpLine %5 12 12
  6615. %71 = OpLoad %PS_OUTPUT %65
  6616. OpLine %5 12 5
  6617. OpStore %66 %71
  6618. %73 = OpExtInst %void %1 DebugNoLine
  6619. %74 = OpExtInst %void %1 DebugNoScope
  6620. %51 = OpLoad %PS_OUTPUT %66
  6621. %53 = OpCompositeExtract %v4float %51 0
  6622. OpStore %out_var_SV_Target0 %53
  6623. OpLine %5 13 1
  6624. OpReturn
  6625. OpFunctionEnd
  6626. )";
  6627. SetTargetEnv(SPV_ENV_VULKAN_1_2);
  6628. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  6629. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  6630. }
  6631. TEST_F(AggressiveDCETest, DebugInfoDeclareKeepsStore) {
  6632. // Verify that local variable tc and its store are kept by DebugDeclare.
  6633. //
  6634. // Same shader source as DebugInfoInFunctionKeepStoreVarElim. The SPIR-V
  6635. // has just been inlined.
  6636. const std::string text = R"(
  6637. OpCapability Shader
  6638. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  6639. OpMemoryModel Logical GLSL450
  6640. OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_sAniso %in_var_TEXCOORD2 %out_var_SV_Target0
  6641. OpExecutionMode %MainPs OriginUpperLeft
  6642. %20 = OpString "foo.frag"
  6643. %24 = OpString "PS_OUTPUT"
  6644. %28 = OpString "float"
  6645. %31 = OpString "vColor"
  6646. %33 = OpString "PS_INPUT"
  6647. %38 = OpString "vTextureCoords"
  6648. %40 = OpString "@type.2d.image"
  6649. %41 = OpString "type.2d.image"
  6650. %43 = OpString "Texture2D.TemplateParam"
  6651. %47 = OpString "src.MainPs"
  6652. %51 = OpString "tc"
  6653. %53 = OpString "ps_output"
  6654. %56 = OpString "i"
  6655. %58 = OpString "@type.sampler"
  6656. %59 = OpString "type.sampler"
  6657. %61 = OpString "g_sAniso"
  6658. %63 = OpString "g_tColor"
  6659. OpName %type_2d_image "type.2d.image"
  6660. OpName %g_tColor "g_tColor"
  6661. OpName %type_sampler "type.sampler"
  6662. OpName %g_sAniso "g_sAniso"
  6663. OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
  6664. OpName %out_var_SV_Target0 "out.var.SV_Target0"
  6665. OpName %MainPs "MainPs"
  6666. OpName %PS_INPUT "PS_INPUT"
  6667. OpMemberName %PS_INPUT 0 "vTextureCoords"
  6668. OpName %param_var_i "param.var.i"
  6669. OpName %PS_OUTPUT "PS_OUTPUT"
  6670. OpMemberName %PS_OUTPUT 0 "vColor"
  6671. OpName %type_sampled_image "type.sampled.image"
  6672. OpDecorate %in_var_TEXCOORD2 Location 0
  6673. OpDecorate %out_var_SV_Target0 Location 0
  6674. OpDecorate %g_tColor DescriptorSet 0
  6675. OpDecorate %g_tColor Binding 0
  6676. OpDecorate %g_sAniso DescriptorSet 0
  6677. OpDecorate %g_sAniso Binding 1
  6678. %int = OpTypeInt 32 1
  6679. %int_0 = OpConstant %int 0
  6680. %uint = OpTypeInt 32 0
  6681. %uint_32 = OpConstant %uint 32
  6682. %float = OpTypeFloat 32
  6683. %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
  6684. %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
  6685. %type_sampler = OpTypeSampler
  6686. %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
  6687. %v2float = OpTypeVector %float 2
  6688. %_ptr_Input_v2float = OpTypePointer Input %v2float
  6689. %v4float = OpTypeVector %float 4
  6690. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6691. %void = OpTypeVoid
  6692. %uint_128 = OpConstant %uint 128
  6693. %uint_0 = OpConstant %uint 0
  6694. %uint_64 = OpConstant %uint 64
  6695. %65 = OpTypeFunction %void
  6696. %PS_INPUT = OpTypeStruct %v2float
  6697. %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
  6698. %PS_OUTPUT = OpTypeStruct %v4float
  6699. %75 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
  6700. %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
  6701. %_ptr_Function_v2float = OpTypePointer Function %v2float
  6702. %type_sampled_image = OpTypeSampledImage %type_2d_image
  6703. %_ptr_Function_v4float = OpTypePointer Function %v4float
  6704. %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
  6705. %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
  6706. %in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
  6707. %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
  6708. %39 = OpExtInst %void %1 DebugInfoNone
  6709. %55 = OpExtInst %void %1 DebugExpression
  6710. %22 = OpExtInst %void %1 DebugSource %20
  6711. %23 = OpExtInst %void %1 DebugCompilationUnit 1 4 %22 HLSL
  6712. %26 = OpExtInst %void %1 DebugTypeComposite %24 Structure %22 10 1 %23 %24 %uint_128 FlagIsProtected|FlagIsPrivate %27
  6713. %29 = OpExtInst %void %1 DebugTypeBasic %28 %uint_32 Float
  6714. %30 = OpExtInst %void %1 DebugTypeVector %29 4
  6715. %27 = OpExtInst %void %1 DebugTypeMember %31 %30 %22 12 5 %26 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
  6716. %35 = OpExtInst %void %1 DebugTypeComposite %33 Structure %22 5 1 %23 %33 %uint_64 FlagIsProtected|FlagIsPrivate %36
  6717. %37 = OpExtInst %void %1 DebugTypeVector %29 2
  6718. %36 = OpExtInst %void %1 DebugTypeMember %38 %37 %22 7 5 %35 %uint_0 %uint_64 FlagIsProtected|FlagIsPrivate
  6719. %42 = OpExtInst %void %1 DebugTypeComposite %40 Class %22 0 0 %23 %41 %39 FlagIsProtected|FlagIsPrivate
  6720. %44 = OpExtInst %void %1 DebugTypeTemplateParameter %43 %29 %39 %22 0 0
  6721. %45 = OpExtInst %void %1 DebugTypeTemplate %42 %44
  6722. %46 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %26 %35
  6723. %48 = OpExtInst %void %1 DebugFunction %47 %46 %22 15 1 %23 %47 FlagIsProtected|FlagIsPrivate 16 %39
  6724. %50 = OpExtInst %void %1 DebugLexicalBlock %22 16 1 %48
  6725. %52 = OpExtInst %void %1 DebugLocalVariable %51 %37 %22 19 12 %50 FlagIsLocal
  6726. %54 = OpExtInst %void %1 DebugLocalVariable %53 %26 %22 17 15 %50 FlagIsLocal
  6727. %57 = OpExtInst %void %1 DebugLocalVariable %56 %35 %22 15 29 %48 FlagIsLocal 1
  6728. %60 = OpExtInst %void %1 DebugTypeComposite %58 Structure %22 0 0 %23 %59 %39 FlagIsProtected|FlagIsPrivate
  6729. %62 = OpExtInst %void %1 DebugGlobalVariable %61 %60 %22 3 14 %23 %61 %g_sAniso FlagIsDefinition
  6730. %64 = OpExtInst %void %1 DebugGlobalVariable %63 %42 %22 1 11 %23 %63 %g_tColor FlagIsDefinition
  6731. %MainPs = OpFunction %void None %65
  6732. %66 = OpLabel
  6733. %114 = OpExtInst %void %1 DebugScope %50
  6734. %98 = OpVariable %_ptr_Function_PS_OUTPUT Function
  6735. %99 = OpVariable %_ptr_Function_v2float Function
  6736. %115 = OpExtInst %void %1 DebugNoScope
  6737. %100 = OpVariable %_ptr_Function_PS_OUTPUT Function
  6738. %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
  6739. %70 = OpLoad %v2float %in_var_TEXCOORD2
  6740. %71 = OpCompositeConstruct %PS_INPUT %70
  6741. OpStore %param_var_i %71
  6742. %116 = OpExtInst %void %1 DebugScope %48
  6743. %102 = OpExtInst %void %1 DebugDeclare %57 %param_var_i %55
  6744. %117 = OpExtInst %void %1 DebugScope %50
  6745. %103 = OpExtInst %void %1 DebugDeclare %54 %98 %55
  6746. OpLine %20 19 17
  6747. %104 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
  6748. %105 = OpLoad %v2float %104
  6749. OpLine %20 19 12
  6750. OpStore %99 %105
  6751. ;CHECK: OpStore %99 %105
  6752. %106 = OpExtInst %void %1 DebugDeclare %52 %99 %55
  6753. OpLine %20 20 26
  6754. %107 = OpLoad %type_2d_image %g_tColor
  6755. OpLine %20 20 46
  6756. %108 = OpLoad %type_sampler %g_sAniso
  6757. OpLine %20 20 26
  6758. %110 = OpSampledImage %type_sampled_image %107 %108
  6759. %111 = OpImageSampleImplicitLod %v4float %110 %105 None
  6760. OpLine %20 20 5
  6761. %112 = OpAccessChain %_ptr_Function_v4float %98 %int_0
  6762. OpStore %112 %111
  6763. OpLine %20 21 12
  6764. %113 = OpLoad %PS_OUTPUT %98
  6765. OpLine %20 21 5
  6766. OpStore %100 %113
  6767. %118 = OpExtInst %void %1 DebugNoScope
  6768. %73 = OpLoad %PS_OUTPUT %100
  6769. %74 = OpCompositeExtract %v4float %73 0
  6770. OpStore %out_var_SV_Target0 %74
  6771. OpReturn
  6772. OpFunctionEnd
  6773. )";
  6774. SetTargetEnv(SPV_ENV_VULKAN_1_2);
  6775. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  6776. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  6777. }
  6778. TEST_F(AggressiveDCETest, DebugInfoValueDerefKeepsStore) {
  6779. // Verify that local variable tc and its store are kept by DebugValue with
  6780. // Deref.
  6781. //
  6782. // Same shader source as DebugInfoInFunctionKeepStoreVarElim. The SPIR-V
  6783. // has just been inlined and edited to replace the DebugDeclare with the
  6784. // DebugValue/Deref.
  6785. const std::string text = R"(
  6786. OpCapability Shader
  6787. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  6788. OpMemoryModel Logical GLSL450
  6789. OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_sAniso %in_var_TEXCOORD2 %out_var_SV_Target0
  6790. OpExecutionMode %MainPs OriginUpperLeft
  6791. %7 = OpString "foo.frag"
  6792. %8 = OpString "PS_OUTPUT"
  6793. %9 = OpString "float"
  6794. %10 = OpString "vColor"
  6795. %11 = OpString "PS_INPUT"
  6796. %12 = OpString "vTextureCoords"
  6797. %13 = OpString "@type.2d.image"
  6798. %14 = OpString "type.2d.image"
  6799. %15 = OpString "Texture2D.TemplateParam"
  6800. %16 = OpString "src.MainPs"
  6801. %17 = OpString "tc"
  6802. %18 = OpString "ps_output"
  6803. %19 = OpString "i"
  6804. %20 = OpString "@type.sampler"
  6805. %21 = OpString "type.sampler"
  6806. %22 = OpString "g_sAniso"
  6807. %23 = OpString "g_tColor"
  6808. OpName %type_2d_image "type.2d.image"
  6809. OpName %g_tColor "g_tColor"
  6810. OpName %type_sampler "type.sampler"
  6811. OpName %g_sAniso "g_sAniso"
  6812. OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
  6813. OpName %out_var_SV_Target0 "out.var.SV_Target0"
  6814. OpName %MainPs "MainPs"
  6815. OpName %PS_INPUT "PS_INPUT"
  6816. OpMemberName %PS_INPUT 0 "vTextureCoords"
  6817. OpName %param_var_i "param.var.i"
  6818. OpName %PS_OUTPUT "PS_OUTPUT"
  6819. OpMemberName %PS_OUTPUT 0 "vColor"
  6820. OpName %type_sampled_image "type.sampled.image"
  6821. OpDecorate %in_var_TEXCOORD2 Location 0
  6822. OpDecorate %out_var_SV_Target0 Location 0
  6823. OpDecorate %g_tColor DescriptorSet 0
  6824. OpDecorate %g_tColor Binding 0
  6825. OpDecorate %g_sAniso DescriptorSet 0
  6826. OpDecorate %g_sAniso Binding 1
  6827. %int = OpTypeInt 32 1
  6828. %int_0 = OpConstant %int 0
  6829. %uint = OpTypeInt 32 0
  6830. %uint_32 = OpConstant %uint 32
  6831. %float = OpTypeFloat 32
  6832. %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
  6833. %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
  6834. %type_sampler = OpTypeSampler
  6835. %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
  6836. %v2float = OpTypeVector %float 2
  6837. %_ptr_Input_v2float = OpTypePointer Input %v2float
  6838. %v4float = OpTypeVector %float 4
  6839. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6840. %void = OpTypeVoid
  6841. %uint_128 = OpConstant %uint 128
  6842. %uint_0 = OpConstant %uint 0
  6843. %uint_64 = OpConstant %uint 64
  6844. %45 = OpTypeFunction %void
  6845. %PS_INPUT = OpTypeStruct %v2float
  6846. %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
  6847. %PS_OUTPUT = OpTypeStruct %v4float
  6848. %47 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
  6849. %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
  6850. %_ptr_Function_v2float = OpTypePointer Function %v2float
  6851. %type_sampled_image = OpTypeSampledImage %type_2d_image
  6852. %_ptr_Function_v4float = OpTypePointer Function %v4float
  6853. %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
  6854. %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
  6855. %in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
  6856. %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
  6857. %51 = OpExtInst %void %1 DebugInfoNone
  6858. %52 = OpExtInst %void %1 DebugExpression
  6859. %53 = OpExtInst %void %1 DebugOperation Deref
  6860. %54 = OpExtInst %void %1 DebugExpression %53
  6861. %55 = OpExtInst %void %1 DebugSource %7
  6862. %56 = OpExtInst %void %1 DebugCompilationUnit 1 4 %55 HLSL
  6863. %57 = OpExtInst %void %1 DebugTypeComposite %8 Structure %55 10 1 %56 %8 %uint_128 FlagIsProtected|FlagIsPrivate %58
  6864. %59 = OpExtInst %void %1 DebugTypeBasic %9 %uint_32 Float
  6865. %60 = OpExtInst %void %1 DebugTypeVector %59 4
  6866. %58 = OpExtInst %void %1 DebugTypeMember %10 %60 %55 12 5 %57 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
  6867. %61 = OpExtInst %void %1 DebugTypeComposite %11 Structure %55 5 1 %56 %11 %uint_64 FlagIsProtected|FlagIsPrivate %62
  6868. %63 = OpExtInst %void %1 DebugTypeVector %59 2
  6869. %62 = OpExtInst %void %1 DebugTypeMember %12 %63 %55 7 5 %61 %uint_0 %uint_64 FlagIsProtected|FlagIsPrivate
  6870. %64 = OpExtInst %void %1 DebugTypeComposite %13 Class %55 0 0 %56 %14 %51 FlagIsProtected|FlagIsPrivate
  6871. %65 = OpExtInst %void %1 DebugTypeTemplateParameter %15 %59 %51 %55 0 0
  6872. %66 = OpExtInst %void %1 DebugTypeTemplate %64 %65
  6873. %67 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %57 %61
  6874. %68 = OpExtInst %void %1 DebugFunction %16 %67 %55 15 1 %56 %16 FlagIsProtected|FlagIsPrivate 16 %51
  6875. %69 = OpExtInst %void %1 DebugLexicalBlock %55 16 1 %68
  6876. %70 = OpExtInst %void %1 DebugLocalVariable %17 %63 %55 19 12 %69 FlagIsLocal
  6877. %71 = OpExtInst %void %1 DebugLocalVariable %18 %57 %55 17 15 %69 FlagIsLocal
  6878. %72 = OpExtInst %void %1 DebugLocalVariable %19 %61 %55 15 29 %68 FlagIsLocal 1
  6879. %73 = OpExtInst %void %1 DebugTypeComposite %20 Structure %55 0 0 %56 %21 %51 FlagIsProtected|FlagIsPrivate
  6880. %74 = OpExtInst %void %1 DebugGlobalVariable %22 %73 %55 3 14 %56 %22 %g_sAniso FlagIsDefinition
  6881. %75 = OpExtInst %void %1 DebugGlobalVariable %23 %64 %55 1 11 %56 %23 %g_tColor FlagIsDefinition
  6882. %MainPs = OpFunction %void None %45
  6883. %76 = OpLabel
  6884. %101 = OpExtInst %void %1 DebugScope %69
  6885. %78 = OpVariable %_ptr_Function_PS_OUTPUT Function
  6886. %79 = OpVariable %_ptr_Function_v2float Function
  6887. %102 = OpExtInst %void %1 DebugNoScope
  6888. %81 = OpVariable %_ptr_Function_PS_OUTPUT Function
  6889. %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
  6890. %82 = OpLoad %v2float %in_var_TEXCOORD2
  6891. %83 = OpCompositeConstruct %PS_INPUT %82
  6892. OpStore %param_var_i %83
  6893. %103 = OpExtInst %void %1 DebugScope %68
  6894. %85 = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
  6895. %104 = OpExtInst %void %1 DebugScope %69
  6896. %87 = OpExtInst %void %1 DebugDeclare %71 %78 %52
  6897. OpLine %7 19 17
  6898. %88 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
  6899. %89 = OpLoad %v2float %88
  6900. OpLine %7 19 12
  6901. OpStore %79 %89
  6902. ;CHECK: OpStore %79 %89
  6903. %90 = OpExtInst %void %1 DebugValue %70 %79 %54
  6904. OpLine %7 20 26
  6905. %91 = OpLoad %type_2d_image %g_tColor
  6906. OpLine %7 20 46
  6907. %92 = OpLoad %type_sampler %g_sAniso
  6908. OpLine %7 20 26
  6909. %94 = OpSampledImage %type_sampled_image %91 %92
  6910. %95 = OpImageSampleImplicitLod %v4float %94 %89 None
  6911. OpLine %7 20 5
  6912. %96 = OpAccessChain %_ptr_Function_v4float %78 %int_0
  6913. OpStore %96 %95
  6914. OpLine %7 21 12
  6915. %97 = OpLoad %PS_OUTPUT %78
  6916. OpLine %7 21 5
  6917. OpStore %81 %97
  6918. %105 = OpExtInst %void %1 DebugNoScope
  6919. %99 = OpLoad %PS_OUTPUT %81
  6920. %100 = OpCompositeExtract %v4float %99 0
  6921. OpStore %out_var_SV_Target0 %100
  6922. OpReturn
  6923. OpFunctionEnd
  6924. )";
  6925. SetTargetEnv(SPV_ENV_VULKAN_1_2);
  6926. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  6927. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  6928. }
  6929. TEST_F(AggressiveDCETest, DebugInfoElimUnusedTextureKeepGlobalVariable) {
  6930. // Verify that unused texture g_tColor2 is eliminated but its
  6931. // DebugGlobalVariable is retained but with DebugInfoNone for its Variable.
  6932. //
  6933. // Same shader source as DebugInfoInFunctionKeepStoreVarElim but with unused
  6934. // g_tColor2 added.
  6935. const std::string text = R"(
  6936. OpCapability Shader
  6937. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  6938. OpMemoryModel Logical GLSL450
  6939. OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_tColor2 %g_sAniso %in_var_TEXCOORD2 %out_var_SV_Target0
  6940. OpExecutionMode %MainPs OriginUpperLeft
  6941. %21 = OpString "foo6.frag"
  6942. %25 = OpString "PS_OUTPUT"
  6943. %29 = OpString "float"
  6944. %32 = OpString "vColor"
  6945. %34 = OpString "PS_INPUT"
  6946. %39 = OpString "vTextureCoords"
  6947. %41 = OpString "@type.2d.image"
  6948. %42 = OpString "type.2d.image"
  6949. %44 = OpString "Texture2D.TemplateParam"
  6950. %48 = OpString "src.MainPs"
  6951. %52 = OpString "tc"
  6952. %54 = OpString "ps_output"
  6953. %57 = OpString "i"
  6954. %59 = OpString "@type.sampler"
  6955. %60 = OpString "type.sampler"
  6956. %62 = OpString "g_sAniso"
  6957. %64 = OpString "g_tColor2"
  6958. %66 = OpString "g_tColor"
  6959. OpName %type_2d_image "type.2d.image"
  6960. OpName %g_tColor "g_tColor"
  6961. OpName %g_tColor2 "g_tColor2"
  6962. OpName %type_sampler "type.sampler"
  6963. OpName %g_sAniso "g_sAniso"
  6964. OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
  6965. OpName %out_var_SV_Target0 "out.var.SV_Target0"
  6966. OpName %MainPs "MainPs"
  6967. OpName %PS_INPUT "PS_INPUT"
  6968. OpMemberName %PS_INPUT 0 "vTextureCoords"
  6969. OpName %param_var_i "param.var.i"
  6970. OpName %PS_OUTPUT "PS_OUTPUT"
  6971. OpMemberName %PS_OUTPUT 0 "vColor"
  6972. OpName %type_sampled_image "type.sampled.image"
  6973. OpDecorate %in_var_TEXCOORD2 Location 0
  6974. OpDecorate %out_var_SV_Target0 Location 0
  6975. OpDecorate %g_tColor DescriptorSet 0
  6976. OpDecorate %g_tColor Binding 0
  6977. OpDecorate %g_tColor2 DescriptorSet 0
  6978. OpDecorate %g_tColor2 Binding 1
  6979. OpDecorate %g_sAniso DescriptorSet 0
  6980. OpDecorate %g_sAniso Binding 2
  6981. %int = OpTypeInt 32 1
  6982. %int_0 = OpConstant %int 0
  6983. %uint = OpTypeInt 32 0
  6984. %uint_32 = OpConstant %uint 32
  6985. %float = OpTypeFloat 32
  6986. %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
  6987. %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
  6988. %type_sampler = OpTypeSampler
  6989. %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
  6990. %v2float = OpTypeVector %float 2
  6991. %_ptr_Input_v2float = OpTypePointer Input %v2float
  6992. %v4float = OpTypeVector %float 4
  6993. %_ptr_Output_v4float = OpTypePointer Output %v4float
  6994. %void = OpTypeVoid
  6995. %uint_128 = OpConstant %uint 128
  6996. %uint_0 = OpConstant %uint 0
  6997. %uint_64 = OpConstant %uint 64
  6998. %68 = OpTypeFunction %void
  6999. %PS_INPUT = OpTypeStruct %v2float
  7000. %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
  7001. %PS_OUTPUT = OpTypeStruct %v4float
  7002. %78 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
  7003. %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
  7004. %_ptr_Function_v2float = OpTypePointer Function %v2float
  7005. %type_sampled_image = OpTypeSampledImage %type_2d_image
  7006. %_ptr_Function_v4float = OpTypePointer Function %v4float
  7007. %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
  7008. %g_tColor2 = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
  7009. ;CHECK-NOT: %g_tColor2 = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
  7010. %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
  7011. %in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
  7012. %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
  7013. %40 = OpExtInst %void %1 DebugInfoNone
  7014. %56 = OpExtInst %void %1 DebugExpression
  7015. %23 = OpExtInst %void %1 DebugSource %21
  7016. %24 = OpExtInst %void %1 DebugCompilationUnit 1 4 %23 HLSL
  7017. %27 = OpExtInst %void %1 DebugTypeComposite %25 Structure %23 11 1 %24 %25 %uint_128 FlagIsProtected|FlagIsPrivate %28
  7018. %30 = OpExtInst %void %1 DebugTypeBasic %29 %uint_32 Float
  7019. %31 = OpExtInst %void %1 DebugTypeVector %30 4
  7020. %28 = OpExtInst %void %1 DebugTypeMember %32 %31 %23 13 5 %27 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
  7021. %36 = OpExtInst %void %1 DebugTypeComposite %34 Structure %23 6 1 %24 %34 %uint_64 FlagIsProtected|FlagIsPrivate %37
  7022. %38 = OpExtInst %void %1 DebugTypeVector %30 2
  7023. %37 = OpExtInst %void %1 DebugTypeMember %39 %38 %23 8 5 %36 %uint_0 %uint_64 FlagIsProtected|FlagIsPrivate
  7024. %43 = OpExtInst %void %1 DebugTypeComposite %41 Class %23 0 0 %24 %42 %40 FlagIsProtected|FlagIsPrivate
  7025. %45 = OpExtInst %void %1 DebugTypeTemplateParameter %44 %30 %40 %23 0 0
  7026. %46 = OpExtInst %void %1 DebugTypeTemplate %43 %45
  7027. %47 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %27 %36
  7028. %49 = OpExtInst %void %1 DebugFunction %48 %47 %23 16 1 %24 %48 FlagIsProtected|FlagIsPrivate 17 %40
  7029. %51 = OpExtInst %void %1 DebugLexicalBlock %23 17 1 %49
  7030. %53 = OpExtInst %void %1 DebugLocalVariable %52 %38 %23 20 12 %51 FlagIsLocal
  7031. %55 = OpExtInst %void %1 DebugLocalVariable %54 %27 %23 18 15 %51 FlagIsLocal
  7032. %58 = OpExtInst %void %1 DebugLocalVariable %57 %36 %23 16 29 %49 FlagIsLocal 1
  7033. %61 = OpExtInst %void %1 DebugTypeComposite %59 Structure %23 0 0 %24 %60 %40 FlagIsProtected|FlagIsPrivate
  7034. %63 = OpExtInst %void %1 DebugGlobalVariable %62 %61 %23 4 14 %24 %62 %g_sAniso FlagIsDefinition
  7035. %65 = OpExtInst %void %1 DebugGlobalVariable %64 %43 %23 2 11 %24 %64 %g_tColor2 FlagIsDefinition
  7036. ;CHECK-NOT: %65 = OpExtInst %void %1 DebugGlobalVariable %64 %43 %23 2 11 %24 %64 %g_tColor2 FlagIsDefinition
  7037. ;CHECK: %65 = OpExtInst %void %1 DebugGlobalVariable %64 %43 %23 2 11 %24 %64 %40 FlagIsDefinition
  7038. %67 = OpExtInst %void %1 DebugGlobalVariable %66 %43 %23 1 11 %24 %66 %g_tColor FlagIsDefinition
  7039. %MainPs = OpFunction %void None %68
  7040. %69 = OpLabel
  7041. %117 = OpExtInst %void %1 DebugScope %51
  7042. %101 = OpVariable %_ptr_Function_PS_OUTPUT Function
  7043. %102 = OpVariable %_ptr_Function_v2float Function
  7044. %118 = OpExtInst %void %1 DebugNoScope
  7045. %103 = OpVariable %_ptr_Function_PS_OUTPUT Function
  7046. %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
  7047. %73 = OpLoad %v2float %in_var_TEXCOORD2
  7048. %74 = OpCompositeConstruct %PS_INPUT %73
  7049. OpStore %param_var_i %74
  7050. %119 = OpExtInst %void %1 DebugScope %49
  7051. %105 = OpExtInst %void %1 DebugDeclare %58 %param_var_i %56
  7052. %120 = OpExtInst %void %1 DebugScope %51
  7053. %106 = OpExtInst %void %1 DebugDeclare %55 %101 %56
  7054. OpLine %21 20 17
  7055. %107 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
  7056. %108 = OpLoad %v2float %107
  7057. OpLine %21 20 12
  7058. OpStore %102 %108
  7059. %109 = OpExtInst %void %1 DebugDeclare %53 %102 %56
  7060. OpLine %21 21 26
  7061. %110 = OpLoad %type_2d_image %g_tColor
  7062. OpLine %21 21 46
  7063. %111 = OpLoad %type_sampler %g_sAniso
  7064. OpLine %21 21 57
  7065. %112 = OpLoad %v2float %102
  7066. OpLine %21 21 26
  7067. %113 = OpSampledImage %type_sampled_image %110 %111
  7068. %114 = OpImageSampleImplicitLod %v4float %113 %112 None
  7069. OpLine %21 21 5
  7070. %115 = OpAccessChain %_ptr_Function_v4float %101 %int_0
  7071. OpStore %115 %114
  7072. OpLine %21 22 12
  7073. %116 = OpLoad %PS_OUTPUT %101
  7074. OpLine %21 22 5
  7075. OpStore %103 %116
  7076. %121 = OpExtInst %void %1 DebugNoScope
  7077. %76 = OpLoad %PS_OUTPUT %103
  7078. %77 = OpCompositeExtract %v4float %76 0
  7079. OpStore %out_var_SV_Target0 %77
  7080. OpReturn
  7081. OpFunctionEnd
  7082. )";
  7083. SetTargetEnv(SPV_ENV_VULKAN_1_2);
  7084. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  7085. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  7086. }
  7087. TEST_F(AggressiveDCETest, KeepDebugScopeParent) {
  7088. // Verify that local variable tc and its store are kept by DebugDeclare.
  7089. //
  7090. // Same shader source as DebugInfoInFunctionKeepStoreVarElim. The SPIR-V
  7091. // has just been inlined.
  7092. const std::string text = R"(
  7093. OpCapability Shader
  7094. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  7095. OpMemoryModel Logical GLSL450
  7096. OpEntryPoint Fragment %main "main" %out_var_SV_TARGET0
  7097. OpExecutionMode %main OriginUpperLeft
  7098. %11 = OpString "float"
  7099. %16 = OpString "t.hlsl"
  7100. %19 = OpString "src.main"
  7101. OpName %out_var_SV_TARGET0 "out.var.SV_TARGET0"
  7102. OpName %main "main"
  7103. OpDecorate %out_var_SV_TARGET0 Location 0
  7104. %float = OpTypeFloat 32
  7105. %float_0 = OpConstant %float 0
  7106. %v4float = OpTypeVector %float 4
  7107. %7 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  7108. %uint = OpTypeInt 32 0
  7109. %uint_32 = OpConstant %uint 32
  7110. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7111. %void = OpTypeVoid
  7112. %23 = OpTypeFunction %void
  7113. %26 = OpTypeFunction %v4float
  7114. %out_var_SV_TARGET0 = OpVariable %_ptr_Output_v4float Output
  7115. %_ptr_Function_v4float = OpTypePointer Function %v4float
  7116. %33 = OpExtInst %void %1 DebugInfoNone
  7117. %13 = OpExtInst %void %1 DebugTypeBasic %11 %uint_32 Float
  7118. %14 = OpExtInst %void %1 DebugTypeVector %13 4
  7119. %15 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %14
  7120. %17 = OpExtInst %void %1 DebugSource %16
  7121. %18 = OpExtInst %void %1 DebugCompilationUnit 1 4 %17 HLSL
  7122. %20 = OpExtInst %void %1 DebugFunction %19 %15 %17 1 1 %18 %19 FlagIsProtected|FlagIsPrivate 2 %33
  7123. %22 = OpExtInst %void %1 DebugLexicalBlock %17 2 1 %20
  7124. %main = OpFunction %void None %23
  7125. %24 = OpLabel
  7126. %31 = OpVariable %_ptr_Function_v4float Function
  7127. ; CHECK: [[block:%\w+]] = OpExtInst %void %1 DebugLexicalBlock
  7128. ; CHECK: DebugScope [[block]]
  7129. %34 = OpExtInst %void %1 DebugScope %22
  7130. OpLine %16 3 5
  7131. OpStore %31 %7
  7132. OpStore %out_var_SV_TARGET0 %7
  7133. %35 = OpExtInst %void %1 DebugNoScope
  7134. OpReturn
  7135. OpFunctionEnd
  7136. )";
  7137. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  7138. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  7139. }
  7140. TEST_F(AggressiveDCETest, KeepExportFunctions) {
  7141. // All functions are reachable. In particular, ExportedFunc and Constant are
  7142. // reachable because ExportedFunc is exported. Nothing should be removed.
  7143. const std::vector<const char*> text = {
  7144. // clang-format off
  7145. "OpCapability Shader",
  7146. "OpCapability Linkage",
  7147. "OpMemoryModel Logical GLSL450",
  7148. "OpEntryPoint Fragment %main \"main\"",
  7149. "OpName %main \"main\"",
  7150. "OpName %ExportedFunc \"ExportedFunc\"",
  7151. "OpName %Live \"Live\"",
  7152. "OpDecorate %ExportedFunc LinkageAttributes \"ExportedFunc\" Export",
  7153. "%void = OpTypeVoid",
  7154. "%7 = OpTypeFunction %void",
  7155. "%main = OpFunction %void None %7",
  7156. "%15 = OpLabel",
  7157. "OpReturn",
  7158. "OpFunctionEnd",
  7159. "%ExportedFunc = OpFunction %void None %7",
  7160. "%19 = OpLabel",
  7161. "%16 = OpFunctionCall %void %Live",
  7162. "OpReturn",
  7163. "OpFunctionEnd",
  7164. "%Live = OpFunction %void None %7",
  7165. "%20 = OpLabel",
  7166. "OpReturn",
  7167. "OpFunctionEnd"
  7168. // clang-format on
  7169. };
  7170. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  7171. std::string assembly = JoinAllInsts(text);
  7172. auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
  7173. assembly, /* skip_nop = */ true, /* do_validation = */ false);
  7174. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  7175. EXPECT_EQ(assembly, std::get<0>(result));
  7176. }
  7177. TEST_F(AggressiveDCETest, KeepPrivateVarInExportFunctions) {
  7178. // The loads and stores from the private variable should not be removed
  7179. // because the functions are exported and could be called.
  7180. const std::string text = R"(OpCapability Shader
  7181. OpCapability Linkage
  7182. OpMemoryModel Logical GLSL450
  7183. OpSource HLSL 630
  7184. OpName %privateVar "privateVar"
  7185. OpName %ReadPrivate "ReadPrivate"
  7186. OpName %WritePrivate "WritePrivate"
  7187. OpName %value "value"
  7188. OpDecorate %ReadPrivate LinkageAttributes "ReadPrivate" Export
  7189. OpDecorate %WritePrivate LinkageAttributes "WritePrivate" Export
  7190. %int = OpTypeInt 32 1
  7191. %_ptr_Private_int = OpTypePointer Private %int
  7192. %6 = OpTypeFunction %int
  7193. %void = OpTypeVoid
  7194. %_ptr_Function_int = OpTypePointer Function %int
  7195. %10 = OpTypeFunction %void %_ptr_Function_int
  7196. %privateVar = OpVariable %_ptr_Private_int Private
  7197. %ReadPrivate = OpFunction %int None %6
  7198. %12 = OpLabel
  7199. %8 = OpLoad %int %privateVar
  7200. OpReturnValue %8
  7201. OpFunctionEnd
  7202. %WritePrivate = OpFunction %void None %10
  7203. %value = OpFunctionParameter %_ptr_Function_int
  7204. %13 = OpLabel
  7205. %14 = OpLoad %int %value
  7206. OpStore %privateVar %14
  7207. OpReturn
  7208. OpFunctionEnd
  7209. )";
  7210. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  7211. auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
  7212. text, /* skip_nop = */ true, /* do_validation = */ false);
  7213. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  7214. EXPECT_EQ(text, std::get<0>(result));
  7215. }
  7216. TEST_F(AggressiveDCETest, KeepLableNames) {
  7217. const std::string text = R"(OpCapability Shader
  7218. OpCapability Linkage
  7219. OpMemoryModel Logical GLSL450
  7220. OpSource HLSL 630
  7221. OpName %WritePrivate "WritePrivate"
  7222. OpName %entry "entry"
  7223. OpName %target "target"
  7224. OpDecorate %WritePrivate LinkageAttributes "WritePrivate" Export
  7225. %void = OpTypeVoid
  7226. %3 = OpTypeFunction %void
  7227. %WritePrivate = OpFunction %void None %3
  7228. %entry = OpLabel
  7229. OpBranch %target
  7230. %target = OpLabel
  7231. OpReturn
  7232. OpFunctionEnd
  7233. )";
  7234. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  7235. auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
  7236. text, /* skip_nop = */ true, /* do_validation = */ false);
  7237. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  7238. EXPECT_EQ(text, std::get<0>(result));
  7239. }
  7240. TEST_F(AggressiveDCETest, PreserveInterface) {
  7241. // Set preserve_interface to true. Verify that unused uniform
  7242. // constant in entry point interface is not eliminated.
  7243. const std::string text = R"(OpCapability RayTracingKHR
  7244. OpExtension "SPV_KHR_ray_tracing"
  7245. %1 = OpExtInstImport "GLSL.std.450"
  7246. OpMemoryModel Logical GLSL450
  7247. OpEntryPoint RayGenerationKHR %2 "main" %3 %4
  7248. OpDecorate %3 Location 0
  7249. OpDecorate %4 DescriptorSet 2
  7250. OpDecorate %4 Binding 0
  7251. %void = OpTypeVoid
  7252. %6 = OpTypeFunction %void
  7253. %uint = OpTypeInt 32 0
  7254. %uint_0 = OpConstant %uint 0
  7255. %float = OpTypeFloat 32
  7256. %_ptr_CallableDataKHR_float = OpTypePointer CallableDataKHR %float
  7257. %3 = OpVariable %_ptr_CallableDataKHR_float CallableDataKHR
  7258. %13 = OpTypeAccelerationStructureKHR
  7259. %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
  7260. %4 = OpVariable %_ptr_UniformConstant_13 UniformConstant
  7261. %2 = OpFunction %void None %6
  7262. %15 = OpLabel
  7263. OpExecuteCallableKHR %uint_0 %3
  7264. OpReturn
  7265. OpFunctionEnd
  7266. )";
  7267. SetTargetEnv(SPV_ENV_VULKAN_1_2);
  7268. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  7269. auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
  7270. text, /* skip_nop = */ true, /* do_validation = */ false,
  7271. /* preserve_interface */ true);
  7272. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  7273. EXPECT_EQ(text, std::get<0>(result));
  7274. }
  7275. TEST_F(AggressiveDCETest, EmptyContinueWithConditionalBranch) {
  7276. const std::string text = R"(OpCapability Shader
  7277. %1 = OpExtInstImport "GLSL.std.450"
  7278. OpMemoryModel Logical GLSL450
  7279. OpEntryPoint Fragment %2 "main"
  7280. OpExecutionMode %2 OriginUpperLeft
  7281. %void = OpTypeVoid
  7282. %4 = OpTypeFunction %void
  7283. %bool = OpTypeBool
  7284. %false = OpConstantFalse %bool
  7285. %2 = OpFunction %void None %4
  7286. %9 = OpLabel
  7287. OpBranch %10
  7288. %10 = OpLabel
  7289. OpLoopMerge %11 %12 None
  7290. OpBranch %13
  7291. %13 = OpLabel
  7292. OpKill
  7293. %12 = OpLabel
  7294. OpBranchConditional %false %10 %10
  7295. %11 = OpLabel
  7296. OpUnreachable
  7297. OpFunctionEnd
  7298. )";
  7299. SetTargetEnv(SPV_ENV_VULKAN_1_2);
  7300. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  7301. SinglePassRunAndCheck<AggressiveDCEPass>(text, text, false);
  7302. }
  7303. TEST_F(AggressiveDCETest, FunctionBecomesUnreachableAfterDCE) {
  7304. const std::string text = R"(
  7305. OpCapability Shader
  7306. %1 = OpExtInstImport "GLSL.std.450"
  7307. OpMemoryModel Logical GLSL450
  7308. OpEntryPoint Fragment %2 "main"
  7309. OpExecutionMode %2 OriginUpperLeft
  7310. OpSource ESSL 320
  7311. %void = OpTypeVoid
  7312. %4 = OpTypeFunction %void
  7313. %int = OpTypeInt 32 1
  7314. %_ptr_Function_int = OpTypePointer Function %int
  7315. %7 = OpTypeFunction %int
  7316. %int_n1 = OpConstant %int -1
  7317. %2 = OpFunction %void None %4
  7318. %9 = OpLabel
  7319. OpKill
  7320. %10 = OpLabel
  7321. %11 = OpFunctionCall %int %12
  7322. OpReturn
  7323. OpFunctionEnd
  7324. ; CHECK: {{%\w+}} = OpFunction %int DontInline|Pure
  7325. %12 = OpFunction %int DontInline|Pure %7
  7326. ; CHECK-NEXT: {{%\w+}} = OpLabel
  7327. %13 = OpLabel
  7328. %14 = OpVariable %_ptr_Function_int Function
  7329. ; CHECK-NEXT: OpBranch [[header:%\w+]]
  7330. OpBranch %15
  7331. ; CHECK-NEXT: [[header]] = OpLabel
  7332. ; CHECK-NEXT: OpBranch [[merge:%\w+]]
  7333. %15 = OpLabel
  7334. OpLoopMerge %16 %17 None
  7335. OpBranch %18
  7336. %18 = OpLabel
  7337. %19 = OpLoad %int %14
  7338. OpBranch %17
  7339. %17 = OpLabel
  7340. OpBranch %15
  7341. ; CHECK-NEXT: [[merge]] = OpLabel
  7342. %16 = OpLabel
  7343. ; CHECK-NEXT: OpReturnValue %int_n1
  7344. OpReturnValue %int_n1
  7345. ; CHECK-NEXT: OpFunctionEnd
  7346. OpFunctionEnd
  7347. )";
  7348. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  7349. }
  7350. TEST_F(AggressiveDCETest, KeepTopLevelDebugInfo) {
  7351. // Don't eliminate DebugCompilationUnit, DebugSourceContinued, and
  7352. // DebugEntryPoint
  7353. const std::string text = R"(
  7354. OpCapability Shader
  7355. OpExtension "SPV_KHR_non_semantic_info"
  7356. %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
  7357. OpMemoryModel Logical GLSL450
  7358. OpEntryPoint Fragment %MainPs "MainPs" %out_var_SV_Target0
  7359. OpExecutionMode %MainPs OriginUpperLeft
  7360. %4 = OpString "foo2.frag"
  7361. %5 = OpString "
  7362. struct PS_OUTPUT
  7363. {
  7364. float4 vColor : SV_Target0 ;
  7365. } ;
  7366. "
  7367. %6 = OpString "
  7368. PS_OUTPUT MainPs ( )
  7369. {
  7370. PS_OUTPUT ps_output ;
  7371. ps_output . vColor = float4( 1.0, 0.0, 0.0, 0.0 );
  7372. return ps_output ;
  7373. }
  7374. "
  7375. %7 = OpString "float"
  7376. %8 = OpString "vColor"
  7377. %9 = OpString "PS_OUTPUT"
  7378. %10 = OpString "MainPs"
  7379. %11 = OpString ""
  7380. %12 = OpString "ps_output"
  7381. %13 = OpString "97a939fb"
  7382. %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"
  7383. OpName %out_var_SV_Target0 "out.var.SV_Target0"
  7384. OpName %MainPs "MainPs"
  7385. OpDecorate %out_var_SV_Target0 Location 0
  7386. %float = OpTypeFloat 32
  7387. %float_1 = OpConstant %float 1
  7388. %float_0 = OpConstant %float 0
  7389. %v4float = OpTypeVector %float 4
  7390. %23 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_0
  7391. %int = OpTypeInt 32 1
  7392. %int_0 = OpConstant %int 0
  7393. %uint = OpTypeInt 32 0
  7394. %uint_32 = OpConstant %uint 32
  7395. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7396. %void = OpTypeVoid
  7397. %uint_1 = OpConstant %uint 1
  7398. %uint_4 = OpConstant %uint 4
  7399. %uint_5 = OpConstant %uint 5
  7400. %uint_3 = OpConstant %uint 3
  7401. %uint_0 = OpConstant %uint 0
  7402. %uint_128 = OpConstant %uint 128
  7403. %uint_12 = OpConstant %uint 12
  7404. %uint_2 = OpConstant %uint 2
  7405. %uint_8 = OpConstant %uint 8
  7406. %uint_7 = OpConstant %uint 7
  7407. %uint_9 = OpConstant %uint 9
  7408. %uint_15 = OpConstant %uint 15
  7409. %42 = OpTypeFunction %void
  7410. %uint_10 = OpConstant %uint 10
  7411. %uint_53 = OpConstant %uint 53
  7412. %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
  7413. %49 = OpExtInst %void %1 DebugExpression
  7414. %50 = OpExtInst %void %1 DebugSource %4 %5
  7415. %51 = OpExtInst %void %1 DebugSourceContinued %6
  7416. ; CHECK: %51 = OpExtInst %void %1 DebugSourceContinued %6
  7417. %52 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %50 %uint_5
  7418. ; CHECK: %52 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %50 %uint_5
  7419. %53 = OpExtInst %void %1 DebugTypeBasic %7 %uint_32 %uint_3 %uint_0
  7420. %54 = OpExtInst %void %1 DebugTypeVector %53 %uint_4
  7421. %55 = OpExtInst %void %1 DebugTypeMember %8 %54 %50 %uint_4 %uint_12 %uint_0 %uint_128 %uint_3
  7422. %56 = OpExtInst %void %1 DebugTypeComposite %9 %uint_1 %50 %uint_2 %uint_8 %52 %9 %uint_128 %uint_3 %55
  7423. %57 = OpExtInst %void %1 DebugTypeFunction %uint_3 %56
  7424. %58 = OpExtInst %void %1 DebugFunction %10 %57 %50 %uint_7 %uint_1 %52 %11 %uint_3 %uint_8
  7425. %59 = OpExtInst %void %1 DebugLexicalBlock %50 %uint_8 %uint_1 %58
  7426. %60 = OpExtInst %void %1 DebugLocalVariable %12 %56 %50 %uint_9 %uint_15 %59 %uint_4
  7427. %61 = OpExtInst %void %1 DebugEntryPoint %58 %52 %13 %14
  7428. ; CHECK: %61 = OpExtInst %void %1 DebugEntryPoint %58 %52 %13 %14
  7429. %MainPs = OpFunction %void None %42
  7430. %62 = OpLabel
  7431. %63 = OpExtInst %void %1 DebugFunctionDefinition %58 %MainPs
  7432. %112 = OpExtInst %void %1 DebugScope %59
  7433. %111 = OpExtInst %void %1 DebugLine %50 %uint_10 %uint_10 %uint_5 %uint_53
  7434. %110 = OpExtInst %void %1 DebugValue %60 %23 %49 %int_0
  7435. %113 = OpExtInst %void %1 DebugNoLine
  7436. %114 = OpExtInst %void %1 DebugNoScope
  7437. OpStore %out_var_SV_Target0 %23
  7438. %66 = OpExtInst %void %1 DebugLine %50 %uint_12 %uint_12 %uint_1 %uint_1
  7439. OpReturn
  7440. OpFunctionEnd
  7441. )";
  7442. SetTargetEnv(SPV_ENV_VULKAN_1_2);
  7443. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  7444. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  7445. }
  7446. TEST_F(AggressiveDCETest, RemoveOutputTrue) {
  7447. // Remove dead n_out output variable from module
  7448. const std::string text = R"(
  7449. OpCapability Shader
  7450. %1 = OpExtInstImport "GLSL.std.450"
  7451. OpMemoryModel Logical GLSL450
  7452. OpEntryPoint Vertex %main "main" %c_out %c_in %n_out
  7453. ;CHECK: OpEntryPoint Vertex %main "main" %c_out %c_in
  7454. OpSource GLSL 450
  7455. OpName %main "main"
  7456. OpName %c_out "c_out"
  7457. OpName %c_in "c_in"
  7458. OpName %n_out "n_out"
  7459. OpDecorate %c_out Location 0
  7460. OpDecorate %c_in Location 0
  7461. OpDecorate %n_out Location 1
  7462. %void = OpTypeVoid
  7463. %3 = OpTypeFunction %void
  7464. %float = OpTypeFloat 32
  7465. %v4float = OpTypeVector %float 4
  7466. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7467. %c_out = OpVariable %_ptr_Output_v4float Output
  7468. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7469. %c_in = OpVariable %_ptr_Input_v4float Input
  7470. %v3float = OpTypeVector %float 3
  7471. %_ptr_Output_v3float = OpTypePointer Output %v3float
  7472. %n_out = OpVariable %_ptr_Output_v3float Output
  7473. %main = OpFunction %void None %3
  7474. %5 = OpLabel
  7475. %12 = OpLoad %v4float %c_in
  7476. OpStore %c_out %12
  7477. OpReturn
  7478. OpFunctionEnd
  7479. )";
  7480. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  7481. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  7482. SinglePassRunAndMatch<AggressiveDCEPass>(text, true, false, true);
  7483. }
  7484. TEST_F(AggressiveDCETest, RemoveOutputFalse) {
  7485. // Remove dead n_out output variable from module
  7486. const std::string text = R"(
  7487. OpCapability Shader
  7488. %1 = OpExtInstImport "GLSL.std.450"
  7489. OpMemoryModel Logical GLSL450
  7490. OpEntryPoint Vertex %main "main" %c_out %c_in %n_out
  7491. ;CHECK: OpEntryPoint Vertex %main "main" %c_out %c_in %n_out
  7492. OpSource GLSL 450
  7493. OpName %main "main"
  7494. OpName %c_out "c_out"
  7495. OpName %c_in "c_in"
  7496. OpName %n_out "n_out"
  7497. OpDecorate %c_out Location 0
  7498. OpDecorate %c_in Location 0
  7499. OpDecorate %n_out Location 1
  7500. %void = OpTypeVoid
  7501. %3 = OpTypeFunction %void
  7502. %float = OpTypeFloat 32
  7503. %v4float = OpTypeVector %float 4
  7504. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7505. %c_out = OpVariable %_ptr_Output_v4float Output
  7506. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7507. %c_in = OpVariable %_ptr_Input_v4float Input
  7508. %v3float = OpTypeVector %float 3
  7509. %_ptr_Output_v3float = OpTypePointer Output %v3float
  7510. %n_out = OpVariable %_ptr_Output_v3float Output
  7511. %main = OpFunction %void None %3
  7512. %5 = OpLabel
  7513. %12 = OpLoad %v4float %c_in
  7514. OpStore %c_out %12
  7515. OpReturn
  7516. OpFunctionEnd
  7517. )";
  7518. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  7519. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  7520. SinglePassRunAndMatch<AggressiveDCEPass>(text, true, false, false);
  7521. }
  7522. TEST_F(AggressiveDCETest, RemoveWhenUsingPrintfExtension) {
  7523. // Remove dead n_out output variable from module
  7524. const std::string text = R"(
  7525. ; CHECK: OpExtInstImport "NonSemantic.DebugPrintf"
  7526. ; CHECK-NOT: OpVariable
  7527. OpCapability Shader
  7528. %1 = OpExtInstImport "NonSemantic.DebugPrintf"
  7529. OpMemoryModel Logical GLSL450
  7530. OpEntryPoint GLCompute %main "main"
  7531. OpExecutionMode %main LocalSize 8 8 1
  7532. OpSource HLSL 660
  7533. OpName %main "main"
  7534. %uint = OpTypeInt 32 0
  7535. %void = OpTypeVoid
  7536. %5 = OpTypeFunction %void
  7537. %_ptr_Function_uint = OpTypePointer Function %uint
  7538. %main = OpFunction %void None %5
  7539. %7 = OpLabel
  7540. %8 = OpVariable %_ptr_Function_uint Function
  7541. OpReturn
  7542. OpFunctionEnd
  7543. )";
  7544. SetTargetEnv(SPV_ENV_VULKAN_1_3);
  7545. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  7546. }
  7547. TEST_F(AggressiveDCETest, FunctionReturnPointer) {
  7548. // Run DCE when a function returning a pointer to a reference is present
  7549. const std::string text = R"(
  7550. OpCapability Shader
  7551. OpCapability PhysicalStorageBufferAddresses
  7552. %1 = OpExtInstImport "GLSL.std.450"
  7553. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  7554. OpEntryPoint Vertex %2 "main" %3 %4
  7555. OpSource GLSL 450
  7556. OpSourceExtension "GL_EXT_buffer_reference"
  7557. OpSourceExtension "GL_EXT_scalar_block_layout"
  7558. OpName %4 "color"
  7559. OpMemberDecorate %5 0 Offset 0
  7560. OpDecorate %5 Block
  7561. OpMemberDecorate %7 0 Offset 0
  7562. OpDecorate %7 Block
  7563. OpDecorate %8 AliasedPointer
  7564. OpDecorate %4 Location 0
  7565. %9 = OpTypeVoid
  7566. %10 = OpTypeFunction %9
  7567. OpTypeForwardPointer %11 PhysicalStorageBuffer
  7568. %12 = OpTypeInt 32 0
  7569. %5 = OpTypeStruct %12
  7570. %11 = OpTypePointer PhysicalStorageBuffer %5
  7571. ;CHECK: [[pt:%\w+]] = OpTypePointer PhysicalStorageBuffer {{%\w+}}
  7572. %13 = OpTypeFunction %11
  7573. ;CHECK: [[pt_fn:%\w+]] = OpTypeFunction [[pt]]
  7574. %7 = OpTypeStruct %11
  7575. %14 = OpTypePointer PushConstant %7
  7576. %3 = OpVariable %14 PushConstant
  7577. %15 = OpTypeInt 32 1
  7578. %16 = OpConstant %15 0
  7579. %17 = OpTypePointer PushConstant %11
  7580. %18 = OpTypePointer Function %11
  7581. %19 = OpTypeFloat 32
  7582. %20 = OpTypeVector %19 4
  7583. %21 = OpTypePointer Output %20
  7584. %4 = OpVariable %21 Output
  7585. %22 = OpConstant %19 1
  7586. %23 = OpConstant %19 0
  7587. %24 = OpConstantComposite %20 %22 %23 %22 %22
  7588. %6 = OpFunction %11 None %13
  7589. ;CHECK: [[fn:%\w+]] = OpFunction [[pt]] None [[pt_fn]]
  7590. %27 = OpLabel
  7591. %28 = OpAccessChain %17 %3 %16
  7592. %29 = OpLoad %11 %28
  7593. OpReturnValue %29
  7594. OpFunctionEnd
  7595. %2 = OpFunction %9 None %10
  7596. %25 = OpLabel
  7597. %8 = OpVariable %18 Function
  7598. %26 = OpFunctionCall %11 %6
  7599. ;CHECK: {{%\w+}} = OpFunctionCall [[pt]] [[fn]]
  7600. OpStore %8 %26
  7601. OpStore %4 %24
  7602. OpReturn
  7603. OpFunctionEnd
  7604. )";
  7605. // For physical storage buffer support
  7606. SetTargetEnv(SPV_ENV_VULKAN_1_2);
  7607. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  7608. }
  7609. TEST_F(AggressiveDCETest, KeepBeginEndInvocationInterlock) {
  7610. // OpBeginInvocationInterlockEXT and OpEndInvocationInterlockEXT delimit a
  7611. // critical section. As such, they should be treated as if they have side
  7612. // effects and should not be removed.
  7613. const std::string test =
  7614. R"(OpCapability Shader
  7615. OpCapability FragmentShaderSampleInterlockEXT
  7616. OpExtension "SPV_EXT_fragment_shader_interlock"
  7617. OpMemoryModel Logical GLSL450
  7618. OpEntryPoint Fragment %1 "main" %gl_FragCoord
  7619. OpExecutionMode %1 OriginUpperLeft
  7620. OpExecutionMode %1 SampleInterlockOrderedEXT
  7621. OpDecorate %gl_FragCoord BuiltIn FragCoord
  7622. %float = OpTypeFloat 32
  7623. %float_0 = OpConstant %float 0
  7624. %v4float = OpTypeVector %float 4
  7625. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7626. %void = OpTypeVoid
  7627. %8 = OpTypeFunction %void
  7628. %bool = OpTypeBool
  7629. %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
  7630. %1 = OpFunction %void None %8
  7631. %10 = OpLabel
  7632. %11 = OpLoad %v4float %gl_FragCoord
  7633. %12 = OpCompositeExtract %float %11 0
  7634. %13 = OpFOrdGreaterThan %bool %12 %float_0
  7635. OpSelectionMerge %14 None
  7636. OpBranchConditional %13 %15 %16
  7637. %15 = OpLabel
  7638. OpBeginInvocationInterlockEXT
  7639. OpBranch %14
  7640. %16 = OpLabel
  7641. OpBeginInvocationInterlockEXT
  7642. OpBranch %14
  7643. %14 = OpLabel
  7644. OpEndInvocationInterlockEXT
  7645. OpReturn
  7646. OpFunctionEnd
  7647. )";
  7648. SinglePassRunAndCheck<AggressiveDCEPass>(test, test, true, true);
  7649. }
  7650. TEST_F(AggressiveDCETest, StoringAPointer) {
  7651. // A store that stores a pointer should not be kept live because the value
  7652. // being stored is eventually loaded from.
  7653. const std::string text = R"(
  7654. OpCapability CooperativeMatrixKHR
  7655. OpCapability Shader
  7656. OpExtension "SPV_KHR_cooperative_matrix"
  7657. OpMemoryModel Logical GLSL450
  7658. OpEntryPoint GLCompute %1 "main" %2
  7659. OpExecutionMode %1 LocalSize 64 1 1
  7660. OpSource HLSL 600
  7661. OpDecorate %2 DescriptorSet 0
  7662. OpDecorate %2 Binding 0
  7663. OpDecorate %_runtimearr_int ArrayStride 4
  7664. OpMemberDecorate %_struct_4 0 Offset 0
  7665. OpDecorate %_struct_4 Block
  7666. %int = OpTypeInt 32 1
  7667. %int_0 = OpConstant %int 0
  7668. %int_1 = OpConstant %int 1
  7669. %uint = OpTypeInt 32 0
  7670. %uint_0 = OpConstant %uint 0
  7671. %uint_64 = OpConstant %uint 64
  7672. %uint_3 = OpConstant %uint 3
  7673. %uint_16 = OpConstant %uint 16
  7674. %uint_4 = OpConstant %uint 4
  7675. %coop_stride = OpConstant %int 42
  7676. %_runtimearr_int = OpTypeRuntimeArray %int
  7677. %_struct_4 = OpTypeStruct %_runtimearr_int
  7678. %_ptr_StorageBuffer__struct_4 = OpTypePointer StorageBuffer %_struct_4
  7679. %void = OpTypeVoid
  7680. %16 = OpTypeFunction %void
  7681. ; CHECK: [[mat:%\w+]] = OpTypeCooperativeMatrixKHR %int %uint_3 %uint_16 %uint_4 %uint_0
  7682. %17 = OpTypeCooperativeMatrixKHR %int %uint_3 %uint_16 %uint_4 %uint_0
  7683. ; CHECK: [[struct:%\w+]] = OpTypeStruct [[mat]]
  7684. %_struct_18 = OpTypeStruct %17
  7685. ; CHECK: [[ptr:%\w+]] = OpTypePointer Function [[struct]]
  7686. %_ptr_Function__struct_18 = OpTypePointer Function %_struct_18
  7687. %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
  7688. %_ptr_Function_17 = OpTypePointer Function %17
  7689. %_ptr_Function_int = OpTypePointer Function %int
  7690. %_ptr_Function__ptr_Function_int = OpTypePointer Function %_ptr_Function_int
  7691. %2 = OpVariable %_ptr_StorageBuffer__struct_4 StorageBuffer
  7692. ; The stored to the fist two variables should be removed and the variables
  7693. ; as well. The only function scope variable should be the cooperative matrix.
  7694. ; CHECK: OpFunction
  7695. ; CHECK-NOT: OpVariable %_ptr_Function__ptr_Function_int Function
  7696. ; CHECK: OpVariable [[ptr]] Function
  7697. ; CHECK-NOT: OpVariable
  7698. %1 = OpFunction %void None %16
  7699. %24 = OpLabel
  7700. %25 = OpVariable %_ptr_Function__ptr_Function_int Function
  7701. %26 = OpVariable %_ptr_Function__ptr_Function_int Function
  7702. %27 = OpVariable %_ptr_Function__struct_18 Function
  7703. %28 = OpAccessChain %_ptr_StorageBuffer_int %2 %int_0 %uint_0
  7704. %29 = OpCooperativeMatrixLoadKHR %17 %28 %int_1 %coop_stride
  7705. %30 = OpCompositeConstruct %_struct_18 %29
  7706. OpStore %27 %30
  7707. %31 = OpAccessChain %_ptr_Function_17 %27 %int_0
  7708. %32 = OpAccessChain %_ptr_Function_int %27 %int_0 %uint_0
  7709. OpStore %26 %32
  7710. %33 = OpLoad %int %32
  7711. %34 = OpIAdd %int %33 %int_1
  7712. OpStore %25 %32
  7713. OpStore %32 %34
  7714. %35 = OpAccessChain %_ptr_StorageBuffer_int %2 %int_0 %uint_64
  7715. %36 = OpLoad %17 %31
  7716. OpCooperativeMatrixStoreKHR %35 %36 %int_0 %coop_stride
  7717. OpReturn
  7718. OpFunctionEnd
  7719. )";
  7720. // For physical storage buffer support
  7721. SetTargetEnv(SPV_ENV_VULKAN_1_2);
  7722. SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
  7723. }
  7724. TEST_F(AggressiveDCETest, FunctionDeclaration) {
  7725. // Ensure the optimizer can handle traversing over a function declaration
  7726. // 'myfunc' which has no blocks
  7727. const std::string text = R"(OpCapability Linkage
  7728. OpCapability Shader
  7729. OpMemoryModel Logical GLSL450
  7730. OpEntryPoint Fragment %PSMain "main" %entryPointParam_PSMain
  7731. OpExecutionMode %PSMain OriginUpperLeft
  7732. OpSource Slang 1
  7733. OpName %myfunc "myfunc"
  7734. OpName %entryPointParam_PSMain "entryPointParam_PSMain"
  7735. OpName %PSMain "PSMain"
  7736. OpDecorate %myfunc LinkageAttributes "_S6myfuncp0pv4f" Import
  7737. OpDecorate %entryPointParam_PSMain Location 0
  7738. %void = OpTypeVoid
  7739. %5 = OpTypeFunction %void
  7740. %float = OpTypeFloat 32
  7741. %v4float = OpTypeVector %float 4
  7742. %8 = OpTypeFunction %v4float
  7743. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7744. %entryPointParam_PSMain = OpVariable %_ptr_Output_v4float Output
  7745. %myfunc = OpFunction %v4float None %8
  7746. OpFunctionEnd
  7747. %PSMain = OpFunction %void None %5
  7748. %10 = OpLabel
  7749. %11 = OpFunctionCall %v4float %myfunc
  7750. OpStore %entryPointParam_PSMain %11
  7751. OpReturn
  7752. OpFunctionEnd
  7753. )";
  7754. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  7755. SinglePassRunAndCheck<AggressiveDCEPass>(text, text, true, true);
  7756. }
  7757. TEST_F(AggressiveDCETest, MarkCentroidInterpolantLive) {
  7758. const std::string spirv =
  7759. R"(OpCapability InterpolationFunction
  7760. OpCapability Shader
  7761. %1 = OpExtInstImport "GLSL.std.450"
  7762. OpMemoryModel Logical GLSL450
  7763. OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_Target
  7764. OpExecutionMode %main OriginUpperLeft
  7765. OpSource HLSL 680
  7766. OpName %in_var_COLOR "in.var.COLOR"
  7767. OpName %out_var_SV_Target "out.var.SV_Target"
  7768. OpName %main "main"
  7769. OpName %param_var_p1 "param.var.p1"
  7770. OpDecorate %in_var_COLOR Location 0
  7771. OpDecorate %out_var_SV_Target Location 0
  7772. %float = OpTypeFloat 32
  7773. %v4float = OpTypeVector %float 4
  7774. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7775. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7776. %void = OpTypeVoid
  7777. %11 = OpTypeFunction %void
  7778. %_ptr_Function_v4float = OpTypePointer Function %v4float
  7779. %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
  7780. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  7781. %main = OpFunction %void None %11
  7782. %13 = OpLabel
  7783. %14 = OpVariable %_ptr_Function_v4float Function
  7784. %param_var_p1 = OpVariable %_ptr_Function_v4float Function
  7785. %15 = OpLoad %v4float %in_var_COLOR
  7786. OpStore %param_var_p1 %15
  7787. %16 = OpExtInst %v4float %1 InterpolateAtCentroid %param_var_p1
  7788. OpStore %14 %16
  7789. %17 = OpLoad %v4float %14
  7790. OpStore %out_var_SV_Target %17
  7791. OpReturn
  7792. OpFunctionEnd
  7793. )";
  7794. SinglePassRunAndCheck<AggressiveDCEPass>(spirv, spirv, true, false);
  7795. }
  7796. TEST_F(AggressiveDCETest, MarkSampleInterpolantLive) {
  7797. const std::string spirv =
  7798. R"(OpCapability InterpolationFunction
  7799. OpCapability Shader
  7800. %1 = OpExtInstImport "GLSL.std.450"
  7801. OpMemoryModel Logical GLSL450
  7802. OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_Target
  7803. OpExecutionMode %main OriginUpperLeft
  7804. OpSource HLSL 680
  7805. OpName %in_var_COLOR "in.var.COLOR"
  7806. OpName %out_var_SV_Target "out.var.SV_Target"
  7807. OpName %main "main"
  7808. OpName %param_var_p1 "param.var.p1"
  7809. OpDecorate %in_var_COLOR Location 0
  7810. OpDecorate %out_var_SV_Target Location 0
  7811. %float = OpTypeFloat 32
  7812. %int = OpTypeInt 32 1
  7813. %v4float = OpTypeVector %float 4
  7814. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7815. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7816. %void = OpTypeVoid
  7817. %12 = OpTypeFunction %void
  7818. %_ptr_Function_v4float = OpTypePointer Function %v4float
  7819. %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
  7820. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  7821. %int_123 = OpConstant %int 123
  7822. %main = OpFunction %void None %12
  7823. %15 = OpLabel
  7824. %16 = OpVariable %_ptr_Function_v4float Function
  7825. %param_var_p1 = OpVariable %_ptr_Function_v4float Function
  7826. %17 = OpLoad %v4float %in_var_COLOR
  7827. OpStore %param_var_p1 %17
  7828. %18 = OpExtInst %v4float %1 InterpolateAtSample %param_var_p1 %int_123
  7829. OpStore %16 %18
  7830. %19 = OpLoad %v4float %16
  7831. OpStore %out_var_SV_Target %19
  7832. OpReturn
  7833. OpFunctionEnd
  7834. )";
  7835. SinglePassRunAndCheck<AggressiveDCEPass>(spirv, spirv, true, false);
  7836. }
  7837. TEST_F(AggressiveDCETest, MarkOffsetInterpolantLive) {
  7838. const std::string spirv =
  7839. R"(OpCapability InterpolationFunction
  7840. OpCapability Shader
  7841. %1 = OpExtInstImport "GLSL.std.450"
  7842. OpMemoryModel Logical GLSL450
  7843. OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_Target
  7844. OpExecutionMode %main OriginUpperLeft
  7845. OpSource HLSL 680
  7846. OpName %in_var_COLOR "in.var.COLOR"
  7847. OpName %out_var_SV_Target "out.var.SV_Target"
  7848. OpName %main "main"
  7849. OpName %param_var_p1 "param.var.p1"
  7850. OpDecorate %in_var_COLOR Location 0
  7851. OpDecorate %out_var_SV_Target Location 0
  7852. %float = OpTypeFloat 32
  7853. %int = OpTypeInt 32 1
  7854. %v4float = OpTypeVector %float 4
  7855. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7856. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7857. %void = OpTypeVoid
  7858. %12 = OpTypeFunction %void
  7859. %_ptr_Function_v4float = OpTypePointer Function %v4float
  7860. %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
  7861. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  7862. %int_123 = OpConstant %int 123
  7863. %main = OpFunction %void None %12
  7864. %15 = OpLabel
  7865. %16 = OpVariable %_ptr_Function_v4float Function
  7866. %param_var_p1 = OpVariable %_ptr_Function_v4float Function
  7867. %17 = OpLoad %v4float %in_var_COLOR
  7868. OpStore %param_var_p1 %17
  7869. %18 = OpExtInst %v4float %1 InterpolateAtOffset %param_var_p1 %int_123
  7870. OpStore %16 %18
  7871. %19 = OpLoad %v4float %16
  7872. OpStore %out_var_SV_Target %19
  7873. OpReturn
  7874. OpFunctionEnd
  7875. )";
  7876. SinglePassRunAndCheck<AggressiveDCEPass>(spirv, spirv, true, false);
  7877. }
  7878. TEST_F(AggressiveDCETest, NoEliminateOpSource) {
  7879. // Should not eliminate OpSource
  7880. const std::string text =
  7881. R"(OpCapability Shader
  7882. OpMemoryModel Logical GLSL450
  7883. OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET
  7884. OpExecutionMode %main OriginUpperLeft
  7885. %4 = OpString "D:\\directxshadercompiler\\tools\\clang\\test\\CodeGenSPIRV\\spirv.debug.opsource.include.hlsl"
  7886. %5 = OpString "D:\\directxshadercompiler\\tools\\clang\\test\\CodeGenSPIRV/spirv.debug.opsource.include-file.hlsli"
  7887. OpSource HLSL 600 %4 "// RUN: %dxc -T ps_6_0 -E main -Zi %s -spirv | FileCheck %s
  7888. #include \"spirv.debug.opsource.include-file.hlsli\"
  7889. struct ColorType
  7890. {
  7891. float4 position : SV_POSITION;
  7892. float4 color : COLOR;
  7893. };
  7894. float4 main(UBER_TYPE(Color) input) : SV_TARGET
  7895. {
  7896. return input.color;
  7897. }
  7898. "
  7899. OpSource HLSL 600 %5 "#define UBER_TYPE(x) x ## Type
  7900. "
  7901. OpName %in_var_COLOR "in.var.COLOR"
  7902. OpName %out_var_SV_TARGET "out.var.SV_TARGET"
  7903. OpName %main "main"
  7904. OpDecorate %in_var_COLOR Location 0
  7905. OpDecorate %out_var_SV_TARGET Location 0
  7906. %float = OpTypeFloat 32
  7907. %v4float = OpTypeVector %float 4
  7908. %_ptr_Input_v4float = OpTypePointer Input %v4float
  7909. %_ptr_Output_v4float = OpTypePointer Output %v4float
  7910. %void = OpTypeVoid
  7911. %11 = OpTypeFunction %void
  7912. %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
  7913. %out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
  7914. OpLine %4 22 1
  7915. %main = OpFunction %void None %11
  7916. OpNoLine
  7917. %12 = OpLabel
  7918. OpLine %4 22 1
  7919. %13 = OpLoad %v4float %in_var_COLOR
  7920. OpStore %out_var_SV_TARGET %13
  7921. OpLine %4 25 1
  7922. OpReturn
  7923. OpFunctionEnd
  7924. )";
  7925. auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
  7926. text, /* skip_nop = */ true, /* skip_validation = */ false);
  7927. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  7928. const std::string& output = std::get<0>(result);
  7929. EXPECT_THAT(
  7930. output,
  7931. HasSubstr("OpSource HLSL 600 %5 \"#define UBER_TYPE(x) x ## Type"));
  7932. }
  7933. TEST_F(AggressiveDCETest, EliminateCopyLogical) {
  7934. const std::string before = R"(
  7935. ; CHECK: [[float32:%\w+]] = OpTypeFloat 32
  7936. ; CHECK: [[v4float:%\w+]] = OpTypeVector [[float32]] 4
  7937. ; CHECK-NOT: %10 = OpTypeArray [[v4float]] %9
  7938. ; CHECK-NOT: %11 = OpTypeStruct %10 %10
  7939. ; CHECK-NOT: %22 = OpTypePointer Uniform %16
  7940. ; CHECK-NOT: %38 = OpTypePointer Function [[v4float]]
  7941. ; CHECK-NOT: %43 = OpTypePointer Function %10
  7942. ; CHECK-NOT: %44 = OpVariable %42 Function
  7943. ; CHECK-NOT: %23 = OpAccessChain %22 %19 %21
  7944. ; CHECK-NOT: %24 = OpLoad %16 %23
  7945. ; CHECK-NOT: %25 = OpCopyLogical %11 %24
  7946. ; CHECK-NOT: %46 = OpCompositeExtract %10 %25 0
  7947. ; CHECK-NOT: OpStore %44 %46
  7948. OpCapability Shader
  7949. %1 = OpExtInstImport "GLSL.std.450"
  7950. OpMemoryModel Logical GLSL450
  7951. OpEntryPoint Vertex %4 "main" %19 %30 %32
  7952. OpSource GLSL 430
  7953. OpName %4 "main"
  7954. OpDecorate %14 ArrayStride 16
  7955. OpDecorate %15 ArrayStride 16
  7956. OpMemberDecorate %16 0 Offset 0
  7957. OpMemberDecorate %16 1 Offset 32
  7958. OpDecorate %17 Block
  7959. OpMemberDecorate %17 0 Offset 0
  7960. OpDecorate %19 Binding 0
  7961. OpDecorate %19 DescriptorSet 0
  7962. OpDecorate %28 Block
  7963. OpMemberDecorate %28 0 BuiltIn Position
  7964. OpMemberDecorate %28 1 BuiltIn PointSize
  7965. OpMemberDecorate %28 2 BuiltIn ClipDistance
  7966. OpDecorate %32 Location 0
  7967. %2 = OpTypeVoid
  7968. %3 = OpTypeFunction %2
  7969. %6 = OpTypeFloat 32
  7970. %7 = OpTypeVector %6 4
  7971. %8 = OpTypeInt 32 0
  7972. %9 = OpConstant %8 2
  7973. %10 = OpTypeArray %7 %9
  7974. %11 = OpTypeStruct %10 %10
  7975. %14 = OpTypeArray %7 %9
  7976. %15 = OpTypeArray %7 %9
  7977. %16 = OpTypeStruct %14 %15
  7978. %17 = OpTypeStruct %16
  7979. %18 = OpTypePointer Uniform %17
  7980. %19 = OpVariable %18 Uniform
  7981. %20 = OpTypeInt 32 1
  7982. %21 = OpConstant %20 0
  7983. %22 = OpTypePointer Uniform %16
  7984. %26 = OpConstant %8 1
  7985. %27 = OpTypeArray %6 %26
  7986. %28 = OpTypeStruct %7 %6 %27
  7987. %29 = OpTypePointer Output %28
  7988. %30 = OpVariable %29 Output
  7989. %31 = OpTypePointer Input %7
  7990. %32 = OpVariable %31 Input
  7991. %33 = OpConstant %8 0
  7992. %34 = OpTypePointer Input %6
  7993. %38 = OpTypePointer Function %7
  7994. %41 = OpTypePointer Output %7
  7995. %43 = OpTypePointer Function %10
  7996. %48 = OpTypePointer Uniform %14
  7997. %49 = OpTypePointer Uniform %7
  7998. %4 = OpFunction %2 None %3
  7999. %5 = OpLabel
  8000. %44 = OpVariable %43 Function
  8001. %23 = OpAccessChain %22 %19 %21
  8002. %24 = OpLoad %16 %23
  8003. %25 = OpCopyLogical %11 %24
  8004. %46 = OpCompositeExtract %10 %25 0
  8005. %50 = OpAccessChain %48 %19 %21 %33
  8006. OpStore %44 %46
  8007. %35 = OpAccessChain %34 %32 %33
  8008. %36 = OpLoad %6 %35
  8009. %37 = OpConvertFToS %20 %36
  8010. %47 = OpAccessChain %49 %50 %37
  8011. %40 = OpLoad %7 %47
  8012. %42 = OpAccessChain %41 %30 %21
  8013. OpStore %42 %40
  8014. OpReturn
  8015. OpFunctionEnd
  8016. )";
  8017. SetTargetEnv(SPV_ENV_UNIVERSAL_1_6);
  8018. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  8019. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
  8020. SinglePassRunAndMatch<AggressiveDCEPass>(before, true);
  8021. }
  8022. TEST_F(AggressiveDCETest, KeepCopyLogical) {
  8023. const std::string before = R"(
  8024. ; CHECK: OpCopyLogical
  8025. OpCapability Shader
  8026. %1 = OpExtInstImport "GLSL.std.450"
  8027. OpMemoryModel Logical GLSL450
  8028. OpEntryPoint GLCompute %4 "main" %15 %23 %38
  8029. OpExecutionMode %4 LocalSize 32 32 1
  8030. OpSource GLSL 430
  8031. OpName %4 "main"
  8032. OpDecorate %10 ArrayStride 16
  8033. OpDecorate %11 ArrayStride 16
  8034. OpMemberDecorate %12 0 Offset 0
  8035. OpMemberDecorate %12 1 Offset 2048
  8036. OpDecorate %13 Block
  8037. OpMemberDecorate %13 0 NonReadable
  8038. OpMemberDecorate %13 0 Offset 0
  8039. OpDecorate %15 NonReadable
  8040. OpDecorate %15 Binding 1
  8041. OpDecorate %15 DescriptorSet 0
  8042. OpDecorate %18 ArrayStride 16
  8043. OpDecorate %19 ArrayStride 16
  8044. OpMemberDecorate %20 0 Offset 0
  8045. OpMemberDecorate %20 1 Offset 2048
  8046. OpDecorate %21 Block
  8047. OpMemberDecorate %21 0 NonWritable
  8048. OpMemberDecorate %21 0 Offset 0
  8049. OpDecorate %23 NonWritable
  8050. OpDecorate %23 Binding 0
  8051. OpDecorate %23 DescriptorSet 0
  8052. OpDecorate %30 ArrayStride 16
  8053. OpDecorate %31 ArrayStride 16
  8054. OpMemberDecorate %32 0 Offset 0
  8055. OpMemberDecorate %32 1 Offset 2048
  8056. OpDecorate %34 ArrayStride 4096
  8057. OpMemberDecorate %35 0 Offset 0
  8058. OpDecorate %36 Block
  8059. OpMemberDecorate %36 0 Offset 0
  8060. OpDecorate %38 Binding 0
  8061. OpDecorate %38 DescriptorSet 0
  8062. %2 = OpTypeVoid
  8063. %3 = OpTypeFunction %2
  8064. %6 = OpTypeFloat 32
  8065. %7 = OpTypeVector %6 4
  8066. %8 = OpTypeInt 32 0
  8067. %9 = OpConstant %8 128
  8068. %10 = OpTypeArray %7 %9
  8069. %11 = OpTypeArray %7 %9
  8070. %12 = OpTypeStruct %10 %11
  8071. %13 = OpTypeStruct %12
  8072. %14 = OpTypePointer StorageBuffer %13
  8073. %15 = OpVariable %14 StorageBuffer
  8074. %16 = OpTypeInt 32 1
  8075. %17 = OpConstant %16 0
  8076. %18 = OpTypeArray %7 %9
  8077. %19 = OpTypeArray %7 %9
  8078. %20 = OpTypeStruct %18 %19
  8079. %21 = OpTypeStruct %20
  8080. %22 = OpTypePointer StorageBuffer %21
  8081. %23 = OpVariable %22 StorageBuffer
  8082. %24 = OpTypePointer StorageBuffer %20
  8083. %27 = OpTypePointer StorageBuffer %12
  8084. %30 = OpTypeArray %7 %9
  8085. %31 = OpTypeArray %7 %9
  8086. %32 = OpTypeStruct %30 %31
  8087. %33 = OpConstant %8 8
  8088. %34 = OpTypeArray %32 %33
  8089. %35 = OpTypeStruct %34
  8090. %36 = OpTypeStruct %35
  8091. %37 = OpTypePointer Uniform %36
  8092. %38 = OpVariable %37 Uniform
  8093. %4 = OpFunction %2 None %3
  8094. %5 = OpLabel
  8095. %25 = OpAccessChain %24 %23 %17
  8096. %26 = OpLoad %20 %25
  8097. %28 = OpAccessChain %27 %15 %17
  8098. %29 = OpCopyLogical %12 %26
  8099. OpStore %28 %29
  8100. OpReturn
  8101. OpFunctionEnd
  8102. )";
  8103. SetTargetEnv(SPV_ENV_UNIVERSAL_1_6);
  8104. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  8105. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
  8106. SinglePassRunAndMatch<AggressiveDCEPass>(before, true);
  8107. }
  8108. } // namespace
  8109. } // namespace opt
  8110. } // namespace spvtools