| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357 |
- // Copyright (c) 2016 Google Inc.
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include "source/opt/fold.h"
- #include <limits>
- #include <memory>
- #include <string>
- #include <vector>
- #include "effcee/effcee.h"
- #include "gmock/gmock.h"
- #include "gtest/gtest.h"
- #include "source/opt/build_module.h"
- #include "source/opt/def_use_manager.h"
- #include "source/opt/ir_context.h"
- #include "source/opt/module.h"
- #include "spirv-tools/libspirv.hpp"
- namespace spvtools {
- namespace opt {
- namespace {
- using ::testing::Contains;
- std::string Disassemble(const std::string& original, IRContext* context,
- uint32_t disassemble_options = 0) {
- std::vector<uint32_t> optimized_bin;
- context->module()->ToBinary(&optimized_bin, true);
- spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2;
- SpirvTools tools(target_env);
- std::string optimized_asm;
- EXPECT_TRUE(
- tools.Disassemble(optimized_bin, &optimized_asm, disassemble_options))
- << "Disassembling failed for shader:\n"
- << original << std::endl;
- return optimized_asm;
- }
- void Match(const std::string& original, IRContext* context,
- uint32_t disassemble_options = 0) {
- std::string disassembly = Disassemble(original, context, disassemble_options);
- auto match_result = effcee::Match(disassembly, original);
- EXPECT_EQ(effcee::Result::Status::Ok, match_result.status())
- << match_result.message() << "\nChecking result:\n"
- << disassembly;
- }
- template <class ResultType>
- struct InstructionFoldingCase {
- InstructionFoldingCase(const std::string& tb, uint32_t id, ResultType result)
- : test_body(tb), id_to_fold(id), expected_result(result) {}
- std::string test_body;
- uint32_t id_to_fold;
- ResultType expected_result;
- };
- std::tuple<std::unique_ptr<IRContext>, Instruction*> GetInstructionToFold(
- const std::string test_body, const uint32_t id_to_fold,
- spv_target_env spv_env) {
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(spv_env, nullptr, test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- EXPECT_NE(nullptr, context);
- if (context == nullptr) {
- return {nullptr, nullptr};
- }
- // Fold the instruction to test.
- if (id_to_fold != 0) {
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(id_to_fold);
- return {std::move(context), inst};
- }
- // If there is not ID, we get the instruction just before a terminator
- // instruction. That could be a return or abort. This is used for cases where
- // the instruction we want to fold does not have a result id.
- Function* func = &*context->module()->begin();
- for (auto& bb : *func) {
- Instruction* terminator = bb.terminator();
- if (terminator->IsReturnOrAbort()) {
- return {std::move(context), terminator->PreviousNode()};
- }
- }
- return {nullptr, nullptr};
- }
- std::tuple<std::unique_ptr<IRContext>, Instruction*> FoldInstruction(
- const std::string test_body, const uint32_t id_to_fold,
- spv_target_env spv_env) {
- // Build module.
- std::unique_ptr<IRContext> context;
- Instruction* inst = nullptr;
- std::tie(context, inst) =
- GetInstructionToFold(test_body, id_to_fold, spv_env);
- if (context == nullptr) {
- return {nullptr, nullptr};
- }
- std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- EXPECT_EQ(inst->result_id(), original_inst->result_id());
- EXPECT_EQ(inst->type_id(), original_inst->type_id());
- if (!succeeded && inst != nullptr) {
- EXPECT_EQ(inst->NumInOperands(), original_inst->NumInOperands());
- for (uint32_t i = 0; i < inst->NumInOperands(); ++i) {
- EXPECT_EQ(inst->GetOperand(i), original_inst->GetOperand(i));
- }
- }
- return {std::move(context), succeeded ? inst : nullptr};
- }
- template <class ElementType, class Function>
- void CheckForExpectedScalarConstant(Instruction* inst,
- ElementType expected_result,
- Function GetValue) {
- ASSERT_TRUE(inst);
- IRContext* context = inst->context();
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- while (inst->opcode() == spv::Op::OpCopyObject) {
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- }
- // Make sure we have a constant.
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::Constant* constant = const_mrg->GetConstantFromInst(inst);
- ASSERT_TRUE(constant);
- // Make sure the constant is a scalar.
- const analysis::ScalarConstant* result = constant->AsScalarConstant();
- ASSERT_TRUE(result);
- // Check if the result matches the expected value.
- // If ExpectedType is not a float type, it should cast the value to a double
- // and never get a nan.
- if (!std::isnan(static_cast<double>(expected_result))) {
- EXPECT_EQ(expected_result, GetValue(result));
- } else {
- EXPECT_TRUE(std::isnan(static_cast<double>(GetValue(result))));
- }
- }
- template <class ElementType, class Function>
- void CheckForExpectedVectorConstant(Instruction* inst,
- std::vector<ElementType> expected_result,
- Function GetValue) {
- ASSERT_TRUE(inst);
- IRContext* context = inst->context();
- EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- std::vector<spv::Op> opcodes = {spv::Op::OpConstantComposite};
- EXPECT_THAT(opcodes, Contains(inst->opcode()));
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::Constant* result = const_mrg->GetConstantFromInst(inst);
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- const std::vector<const analysis::Constant*>& componenets =
- result->AsVectorConstant()->GetComponents();
- EXPECT_EQ(componenets.size(), expected_result.size());
- for (size_t i = 0; i < componenets.size(); i++) {
- EXPECT_EQ(expected_result[i], GetValue(componenets[i]));
- }
- }
- }
- using IntegerInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<uint32_t>>;
- TEST_P(IntegerInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- CheckForExpectedScalarConstant(
- inst, tc.expected_result, [](const analysis::Constant* c) {
- return c->AsScalarConstant()->GetU32BitValue();
- });
- }
- // Returns a common SPIR-V header for all of the test that follow.
- #define INT_0_ID 100
- #define TRUE_ID 101
- #define VEC2_0_ID 102
- #define INT_7_ID 103
- #define FLOAT_0_ID 104
- #define DOUBLE_0_ID 105
- #define VEC4_0_ID 106
- #define DVEC4_0_ID 106
- #define HALF_0_ID 108
- #define UINT_0_ID 109
- #define INT_NULL_ID 110
- #define UINT_NULL_ID 111
- const std::string& Header() {
- static const std::string header = R"(OpCapability Shader
- OpCapability Float16
- OpCapability Float64
- OpCapability Int8
- OpCapability Int16
- OpCapability Int64
- OpCapability CooperativeMatrixKHR
- OpExtension "SPV_KHR_cooperative_matrix"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 140
- OpName %main "main"
- %void = OpTypeVoid
- %void_func = OpTypeFunction %void
- %bool = OpTypeBool
- %float = OpTypeFloat 32
- %double = OpTypeFloat 64
- %half = OpTypeFloat 16
- %101 = OpConstantTrue %bool ; Need a def with an numerical id to define id maps.
- %true = OpConstantTrue %bool
- %false = OpConstantFalse %bool
- %bool_null = OpConstantNull %bool
- %short = OpTypeInt 16 1
- %ushort = OpTypeInt 16 0
- %byte = OpTypeInt 8 1
- %ubyte = OpTypeInt 8 0
- %int = OpTypeInt 32 1
- %long = OpTypeInt 64 1
- %uint = OpTypeInt 32 0
- %ulong = OpTypeInt 64 0
- %v2int = OpTypeVector %int 2
- %v4int = OpTypeVector %int 4
- %v2short = OpTypeVector %short 2
- %v2long = OpTypeVector %long 2
- %v4long = OpTypeVector %long 4
- %v4float = OpTypeVector %float 4
- %v4double = OpTypeVector %double 4
- %v2uint = OpTypeVector %uint 2
- %v2ulong = OpTypeVector %ulong 2
- %v2float = OpTypeVector %float 2
- %v2double = OpTypeVector %double 2
- %v2half = OpTypeVector %half 2
- %v2bool = OpTypeVector %bool 2
- %m2x2int = OpTypeMatrix %v2int 2
- %mat4v2float = OpTypeMatrix %v2float 4
- %mat2v4float = OpTypeMatrix %v4float 2
- %mat4v4float = OpTypeMatrix %v4float 4
- %mat4v4double = OpTypeMatrix %v4double 4
- %struct_v2int_int_int = OpTypeStruct %v2int %int %int
- %_ptr_int = OpTypePointer Function %int
- %_ptr_uint = OpTypePointer Function %uint
- %_ptr_bool = OpTypePointer Function %bool
- %_ptr_float = OpTypePointer Function %float
- %_ptr_double = OpTypePointer Function %double
- %_ptr_half = OpTypePointer Function %half
- %_ptr_long = OpTypePointer Function %long
- %_ptr_ulong = OpTypePointer Function %ulong
- %_ptr_v2int = OpTypePointer Function %v2int
- %_ptr_v4int = OpTypePointer Function %v4int
- %_ptr_v4float = OpTypePointer Function %v4float
- %_ptr_v4double = OpTypePointer Function %v4double
- %_ptr_struct_v2int_int_int = OpTypePointer Function %struct_v2int_int_int
- %_ptr_v2float = OpTypePointer Function %v2float
- %_ptr_v2double = OpTypePointer Function %v2double
- %int_2 = OpConstant %int 2
- %int_arr_2 = OpTypeArray %int %int_2
- %short_0 = OpConstant %short 0
- %short_2 = OpConstant %short 2
- %short_3 = OpConstant %short 3
- %short_n5 = OpConstant %short -5
- %ubyte_1 = OpConstant %ubyte 1
- %byte_n1 = OpConstant %byte -1
- %100 = OpConstant %int 0 ; Need a def with an numerical id to define id maps.
- %110 = OpConstantNull %int ; Need a def with an numerical id to define id maps.
- %103 = OpConstant %int 7 ; Need a def with an numerical id to define id maps.
- %int_0 = OpConstant %int 0
- %int_1 = OpConstant %int 1
- %int_3 = OpConstant %int 3
- %int_4 = OpConstant %int 4
- %int_10 = OpConstant %int 10
- %int_1073741824 = OpConstant %int 1073741824
- %int_n1 = OpConstant %int -1
- %int_n24 = OpConstant %int -24
- %int_n858993459 = OpConstant %int -858993459
- %int_min = OpConstant %int -2147483648
- %int_max = OpConstant %int 2147483647
- %long_0 = OpConstant %long 0
- %long_1 = OpConstant %long 1
- %long_2 = OpConstant %long 2
- %long_3 = OpConstant %long 3
- %long_n3 = OpConstant %long -3
- %long_7 = OpConstant %long 7
- %long_n7 = OpConstant %long -7
- %long_10 = OpConstant %long 10
- %long_32768 = OpConstant %long 32768
- %long_n57344 = OpConstant %long -57344
- %long_n4611686018427387904 = OpConstant %long -4611686018427387904
- %long_4611686018427387904 = OpConstant %long 4611686018427387904
- %long_n1 = OpConstant %long -1
- %long_n3689348814741910323 = OpConstant %long -3689348814741910323
- %long_min = OpConstant %long -9223372036854775808
- %long_max = OpConstant %long 9223372036854775807
- %ulong_7 = OpConstant %ulong 7
- %ulong_4611686018427387904 = OpConstant %ulong 4611686018427387904
- %109 = OpConstant %uint 0 ; Need a def with an numerical id to define id maps.
- %111 = OpConstantNull %uint ; Need a def with an numerical id to define id maps.
- %uint_0 = OpConstant %uint 0
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %uint_3 = OpConstant %uint 3
- %uint_4 = OpConstant %uint 4
- %uint_32 = OpConstant %uint 32
- %uint_42 = OpConstant %uint 42
- %uint_2147483649 = OpConstant %uint 2147483649
- %uint_max = OpConstant %uint 4294967295
- %ulong_0 = OpConstant %ulong 0
- %ulong_1 = OpConstant %ulong 1
- %ulong_2 = OpConstant %ulong 2
- %ulong_9223372036854775809 = OpConstant %ulong 9223372036854775809
- %ulong_max = OpConstant %ulong 18446744073709551615
- %v2int_undef = OpUndef %v2int
- %v2int_0_0 = OpConstantComposite %v2int %int_0 %int_0
- %v2int_1_0 = OpConstantComposite %v2int %int_1 %int_0
- %v2int_2_2 = OpConstantComposite %v2int %int_2 %int_2
- %v2int_2_3 = OpConstantComposite %v2int %int_2 %int_3
- %v2int_3_2 = OpConstantComposite %v2int %int_3 %int_2
- %v2int_n1_n24 = OpConstantComposite %v2int %int_n1 %int_n24
- %v2int_4_4 = OpConstantComposite %v2int %int_4 %int_4
- %v2int_min_max = OpConstantComposite %v2int %int_min %int_max
- %v2short_2_n5 = OpConstantComposite %v2short %short_2 %short_n5
- %v2long_2_2 = OpConstantComposite %v2long %long_2 %long_2
- %v2long_2_3 = OpConstantComposite %v2long %long_2 %long_3
- %v2bool_null = OpConstantNull %v2bool
- %v2bool_true_false = OpConstantComposite %v2bool %true %false
- %v2bool_false_true = OpConstantComposite %v2bool %false %true
- %struct_v2int_int_int_null = OpConstantNull %struct_v2int_int_int
- %v2int_null = OpConstantNull %v2int
- %102 = OpConstantComposite %v2int %103 %103
- %v4int_undef = OpUndef %v4int
- %v4int_0_0_0_0 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
- %m2x2int_undef = OpUndef %m2x2int
- %struct_undef_0_0 = OpConstantComposite %struct_v2int_int_int %v2int_undef %int_0 %int_0
- %float_n1 = OpConstant %float -1
- %104 = OpConstant %float 0 ; Need a def with an numerical id to define id maps.
- %float_null = OpConstantNull %float
- %float_0 = OpConstant %float 0
- %float_n0 = OpConstant %float -0.0
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %float_3 = OpConstant %float 3
- %float_4 = OpConstant %float 4
- %float_2049 = OpConstant %float 2049
- %float_n2049 = OpConstant %float -2049
- %float_0p5 = OpConstant %float 0.5
- %float_0p2 = OpConstant %float 0.2
- %float_pi = OpConstant %float 1.5555
- %float_1e16 = OpConstant %float 1e16
- %float_n1e16 = OpConstant %float -1e16
- %float_1en16 = OpConstant %float 1e-16
- %float_n1en16 = OpConstant %float -1e-16
- %v2float_0_0 = OpConstantComposite %v2float %float_0 %float_0
- %v2float_2_2 = OpConstantComposite %v2float %float_2 %float_2
- %v2float_2_3 = OpConstantComposite %v2float %float_2 %float_3
- %v2float_3_2 = OpConstantComposite %v2float %float_3 %float_2
- %v2float_4_4 = OpConstantComposite %v2float %float_4 %float_4
- %v2float_2_0p5 = OpConstantComposite %v2float %float_2 %float_0p5
- %v2float_0p2_0p5 = OpConstantComposite %v2float %float_0p2 %float_0p5
- %v2float_null = OpConstantNull %v2float
- %double_n1 = OpConstant %double -1
- %105 = OpConstant %double 0 ; Need a def with an numerical id to define id maps.
- %double_null = OpConstantNull %double
- %double_0 = OpConstant %double 0
- %double_n0 = OpConstant %double -0.0
- %double_1 = OpConstant %double 1
- %double_2 = OpConstant %double 2
- %double_3 = OpConstant %double 3
- %double_4 = OpConstant %double 4
- %double_5 = OpConstant %double 5
- %double_0p5 = OpConstant %double 0.5
- %double_0p2 = OpConstant %double 0.2
- %v2double_0_0 = OpConstantComposite %v2double %double_0 %double_0
- %v2double_2_2 = OpConstantComposite %v2double %double_2 %double_2
- %v2double_2_3 = OpConstantComposite %v2double %double_2 %double_3
- %v2double_3_2 = OpConstantComposite %v2double %double_3 %double_2
- %v2double_4_4 = OpConstantComposite %v2double %double_4 %double_4
- %v2double_2_0p5 = OpConstantComposite %v2double %double_2 %double_0p5
- %v2double_null = OpConstantNull %v2double
- %108 = OpConstant %half 0
- %half_1 = OpConstant %half 1
- %half_2 = OpConstant %half 2
- %half_0_1 = OpConstantComposite %v2half %108 %half_1
- %106 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %v4float_0_0_0_0 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %v4float_0_0_0_1 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
- %v4float_0_1_0_0 = OpConstantComposite %v4float %float_0 %float_1 %float_null %float_0
- %v4float_1_1_1_1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
- %v4float_1_2_3_4 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
- %v4float_null = OpConstantNull %v4float
- %mat2v4float_null = OpConstantNull %mat2v4float
- %mat4v4float_null = OpConstantNull %mat4v4float
- %mat4v4float_1_2_3_4 = OpConstantComposite %mat4v4float %v4float_1_2_3_4 %v4float_1_2_3_4 %v4float_1_2_3_4 %v4float_1_2_3_4
- %mat4v4float_1_2_3_4_null = OpConstantComposite %mat4v4float %v4float_1_2_3_4 %v4float_null %v4float_1_2_3_4 %v4float_null
- %107 = OpConstantComposite %v4double %double_0 %double_0 %double_0 %double_0
- %v4double_0_0_0_0 = OpConstantComposite %v4double %double_0 %double_0 %double_0 %double_0
- %v4double_0_0_0_1 = OpConstantComposite %v4double %double_0 %double_0 %double_0 %double_1
- %v4double_0_1_0_0 = OpConstantComposite %v4double %double_0 %double_1 %double_null %double_0
- %v4double_1_1_1_1 = OpConstantComposite %v4double %double_1 %double_1 %double_1 %double_1
- %v4double_1_2_3_4 = OpConstantComposite %v4double %double_1 %double_2 %double_3 %double_4
- %v4double_1_1_1_0p5 = OpConstantComposite %v4double %double_1 %double_1 %double_1 %double_0p5
- %v4double_null = OpConstantNull %v4double
- %mat4v4double_null = OpConstantNull %mat4v4double
- %mat4v4double_1_2_3_4 = OpConstantComposite %mat4v4double %v4double_1_2_3_4 %v4double_1_2_3_4 %v4double_1_2_3_4 %v4double_1_2_3_4
- %mat4v4double_1_2_3_4_null = OpConstantComposite %mat4v4double %v4double_1_2_3_4 %v4double_null %v4double_1_2_3_4 %v4double_null
- %v4float_n1_2_1_3 = OpConstantComposite %v4float %float_n1 %float_2 %float_1 %float_3
- %uint_0x3f800000 = OpConstant %uint 0x3f800000
- %uint_0xbf800000 = OpConstant %uint 0xbf800000
- %v2uint_0x3f800000_0xbf800000 = OpConstantComposite %v2uint %uint_0x3f800000 %uint_0xbf800000
- %long_0xbf8000003f800000 = OpConstant %long 0xbf8000003f800000
- %int_0x3FF00000 = OpConstant %int 0x3FF00000
- %int_0x00000000 = OpConstant %int 0x00000000
- %int_0xC05FD666 = OpConstant %int 0xC05FD666
- %int_0x66666666 = OpConstant %int 0x66666666
- %v4int_0x3FF00000_0x00000000_0xC05FD666_0x66666666 = OpConstantComposite %v4int %int_0x00000000 %int_0x3FF00000 %int_0x66666666 %int_0xC05FD666
- %ushort_0x4400 = OpConstant %ushort 0x4400
- %short_0x4400 = OpConstant %short 0x4400
- %ushort_0xBC00 = OpConstant %ushort 0xBC00
- %short_0xBC00 = OpConstant %short 0xBC00
- %int_arr_2_undef = OpUndef %int_arr_2
- %int_coop_matrix = OpTypeCooperativeMatrixKHR %int %uint_3 %uint_3 %uint_32 %uint_0
- %undef_int_coop_matrix = OpUndef %int_coop_matrix
- %uint_coop_matrix = OpTypeCooperativeMatrixKHR %uint %uint_3 %uint_3 %uint_32 %uint_0
- %undef_uint_coop_matrix = OpUndef %uint_coop_matrix
- %float_coop_matrix = OpTypeCooperativeMatrixKHR %float %uint_3 %uint_3 %uint_32 %uint_0
- %undef_float_coop_matrix = OpUndef %float_coop_matrix
- )";
- return header;
- }
- // Returns the header with definitions of float NaN and double NaN. Since FC
- // "; CHECK: [[double_n0:%\\w+]] = OpConstant [[double]] -0\n" finds
- // %double_nan = OpConstant %double -0x1.8p+1024 instead of
- // %double_n0 = OpConstant %double -0,
- // we separates those definitions from Header().
- const std::string& HeaderWithNaN() {
- static const std::string headerWithNaN =
- Header() +
- R"(%float_nan = OpConstant %float -0x1.8p+128
- %double_nan = OpConstant %double -0x1.8p+1024
- )";
- return headerWithNaN;
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold 0*n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpIMul %int %int_0 %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 1: fold n*0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpIMul %int %load %int_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 2: fold 0/n (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSDiv %int %int_0 %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 3: fold n/0 (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSDiv %int %load %int_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 4: fold 0/n (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpUDiv %uint %uint_0 %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 5: fold n/0 (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSDiv %int %load %int_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 6: fold 0 remainder n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSRem %int %int_0 %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 7: fold n remainder 0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSRem %int %load %int_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 8: fold 0%n (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSMod %int %int_0 %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 9: fold n%0 (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSMod %int %load %int_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 10: fold 0%n (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpUMod %uint %uint_0 %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 11: fold n%0 (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpUMod %uint %load %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 12: fold n << 32
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpShiftLeftLogical %uint %load %uint_32\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 13: fold n >> 32
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpShiftRightLogical %uint %load %uint_32\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 14: fold n | 0xFFFFFFFF
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpBitwiseOr %uint %load %uint_max\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0xFFFFFFFF),
- // Test case 15: fold 0xFFFFFFFF | n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpBitwiseOr %uint %uint_max %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0xFFFFFFFF),
- // Test case 16: fold n & 0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpBitwiseAnd %uint %load %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 17: fold 1/0 (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSDiv %int %int_1 %int_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 18: fold 1/0 (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpUDiv %uint %uint_1 %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 19: fold OpSRem 1 0 (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSRem %int %int_1 %int_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 20: fold 1%0 (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSMod %int %int_1 %int_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 21: fold 1%0 (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpUMod %uint %uint_1 %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 22: fold unsigned n >> 42 (undefined, so set to zero).
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpShiftRightLogical %uint %load %uint_42\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 23: fold signed n >> 42 (undefined, so set to zero).
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpShiftRightLogical %int %load %uint_42\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 24: fold n << 42 (undefined, so set to zero).
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpShiftLeftLogical %int %load %uint_42\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 25: fold -24 >> 32 (defined as -1)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpShiftRightArithmetic %int %int_n24 %uint_32\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -1),
- // Test case 26: fold 2 >> 32 (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpShiftRightArithmetic %int %int_2 %uint_32\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 27: fold 2 >> 32 (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpShiftRightLogical %int %int_2 %uint_32\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 28: fold 2 << 32
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpShiftLeftLogical %int %int_2 %uint_32\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 29: fold -INT_MIN
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSNegate %int %int_min\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<int32_t>::min()),
- // Test case 30: fold UMin 3 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UMin %uint_3 %uint_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 31: fold UMin 4 2
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UMin %uint_4 %uint_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2),
- // Test case 32: fold SMin 3 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 UMin %int_3 %int_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 33: fold SMin 4 2
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 SMin %int_4 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2),
- // Test case 34: fold UMax 3 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UMax %uint_3 %uint_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4),
- // Test case 35: fold UMax 3 2
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UMax %uint_3 %uint_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 36: fold SMax 3 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 UMax %int_3 %int_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4),
- // Test case 37: fold SMax 3 2
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 SMax %int_3 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 38: fold UClamp 2 3 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UClamp %uint_2 %uint_3 %uint_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 39: fold UClamp 2 0 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UClamp %uint_2 %uint_0 %uint_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2),
- // Test case 40: fold UClamp 2 0 1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UClamp %uint_2 %uint_0 %uint_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1),
- // Test case 41: fold SClamp 2 3 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 SClamp %int_2 %int_3 %int_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 42: fold SClamp 2 0 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 SClamp %int_2 %int_0 %int_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2),
- // Test case 43: fold SClamp 2 0 1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 SClamp %int_2 %int_0 %int_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1),
- // Test case 44: SClamp 1 2 x
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %int\n" +
- "%2 = OpExtInst %int %1 SClamp %int_1 %int_2 %undef\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2),
- // Test case 45: SClamp 2 x 1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %int\n" +
- "%2 = OpExtInst %int %1 SClamp %int_2 %undef %int_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1),
- // Test case 46: UClamp 1 2 x
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %uint\n" +
- "%2 = OpExtInst %uint %1 UClamp %uint_1 %uint_2 %undef\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2),
- // Test case 47: UClamp 2 x 1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %uint\n" +
- "%2 = OpExtInst %uint %1 UClamp %uint_2 %undef %uint_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1),
- // Test case 48: Bit-cast int 0 to unsigned int
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %uint %int_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 49: Bit-cast int -24 to unsigned int
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %uint %int_n24\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, static_cast<uint32_t>(-24)),
- // Test case 50: Bit-cast float 1.0f to unsigned int
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %uint %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, static_cast<uint32_t>(0x3f800000)),
- // Test case 51: Bit-cast ushort 0xBC00 to ushort
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %ushort %ushort_0xBC00\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0xBC00),
- // Test case 52: Bit-cast short 0xBC00 to ushort
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %ushort %short_0xBC00\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0xBC00),
- // Test case 53: Bit-cast half 1 to ushort
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %ushort %half_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0x3C00),
- // Test case 54: Bit-cast ushort 0xBC00 to short
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %short %ushort_0xBC00\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0xFFFFBC00),
- // Test case 55: Bit-cast short 0xBC00 to short
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %short %short_0xBC00\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0xFFFFBC00),
- // Test case 56: Bit-cast half 1 to short
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %short %half_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0x3C00),
- // Test case 57: Bit-cast ushort 0xBC00 to half
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %half %ushort_0xBC00\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0xBC00),
- // Test case 58: Bit-cast short 0xBC00 to half
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %half %short_0xBC00\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0xFFFFBC00),
- // Test case 59: Bit-cast half 1 to half
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %half %half_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0x3C00),
- // Test case 60: Bit-cast ubyte 1 to byte
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %byte %ubyte_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1),
- // Test case 61: Bit-cast byte -1 to ubyte
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %ubyte %byte_n1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0xFF),
- // Test case 62: Negate 2.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSNegate %int %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -2),
- // Test case 63: Negate negative short.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSNegate %short %short_0xBC00\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0x4400 /* expected to be sign extended. */),
- // Test case 64: Negate positive short.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSNegate %short %short_0x4400\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0xFFFFBC00 /* expected to be sign extended. */),
- // Test case 65: Negate a negative short.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSNegate %ushort %ushort_0xBC00\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0x4400 /* expected to be zero extended. */),
- // Test case 66: Negate positive short.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSNegate %ushort %ushort_0x4400\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0xBC00 /* expected to be zero extended. */),
- // Test case 67: Fold 2 + 3 (short)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpIAdd %short %short_2 %short_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 5),
- // Test case 68: Fold 2 + -5 (short)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpIAdd %short %short_2 %short_n5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -3),
- // Test case 69: Fold int(3ll)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSConvert %int %long_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 70: Fold short(-3ll)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSConvert %short %long_n3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -3),
- // Test case 71: Fold short(32768ll) - This should do a sign extend when
- // converting to short.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSConvert %short %long_32768\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -32768),
- // Test case 72: Fold short(-57344) - This should do a sign extend when
- // converting to short making the upper bits 0.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSConvert %short %long_n57344\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 8192),
- // Test case 73: Fold int(-5(short)). The -5 should be interpreted as an unsigned value, and be zero extended to 32-bits.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpUConvert %uint %short_n5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 65531),
- // Test case 74: Fold short(-24(int)). The upper bits should be cleared. So 0xFFFFFFE8 should become 0x0000FFE8.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpUConvert %ushort %int_n24\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 65512)
- ));
- // clang-format on
- using LongIntegerInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<uint64_t>>;
- TEST_P(LongIntegerInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- CheckForExpectedScalarConstant(
- inst, tc.expected_result, [](const analysis::Constant* c) {
- return c->AsScalarConstant()->GetU64BitValue();
- });
- }
- INSTANTIATE_TEST_SUITE_P(
- TestCase, LongIntegerInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold 1+4611686018427387904
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpIAdd %long %long_1 %long_4611686018427387904\n" +
- "OpReturn\n" + "OpFunctionEnd",
- 2, 1 + 4611686018427387904),
- // Test case 1: fold 1-4611686018427387904
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpISub %long %long_1 %long_4611686018427387904\n" +
- "OpReturn\n" + "OpFunctionEnd",
- 2, 1 - 4611686018427387904),
- // Test case 2: fold 2*4611686018427387904
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpIMul %long %long_2 %long_4611686018427387904\n" +
- "OpReturn\n" + "OpFunctionEnd",
- 2, 9223372036854775808ull),
- // Test case 3: fold 4611686018427387904/2 (unsigned)
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpUDiv %ulong %ulong_4611686018427387904 %ulong_2\n" +
- "OpReturn\n" + "OpFunctionEnd",
- 2, 4611686018427387904 / 2),
- // Test case 4: fold 4611686018427387904/2 (signed)
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSDiv %long %long_4611686018427387904 %long_2\n" +
- "OpReturn\n" + "OpFunctionEnd",
- 2, 4611686018427387904 / 2),
- // Test case 5: fold -4611686018427387904/2 (signed)
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSDiv %long %long_n4611686018427387904 %long_2\n" +
- "OpReturn\n" + "OpFunctionEnd",
- 2, -4611686018427387904 / 2),
- // Test case 6: fold 4611686018427387904 mod 7 (unsigned)
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpUMod %ulong %ulong_4611686018427387904 %ulong_7\n" +
- "OpReturn\n" + "OpFunctionEnd",
- 2, 4611686018427387904ull % 7ull),
- // Test case 7: fold 7 mod 3 (signed)
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSMod %long %long_7 %long_3\n" + "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1ull),
- // Test case 8: fold 7 rem 3 (signed)
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSRem %long %long_7 %long_3\n" + "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1ull),
- // Test case 9: fold 7 mod -3 (signed)
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSMod %long %long_7 %long_n3\n" + "OpReturn\n" +
- "OpFunctionEnd",
- 2, -2ll),
- // Test case 10: fold 7 rem 3 (signed)
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSRem %long %long_7 %long_n3\n" + "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1ll),
- // Test case 11: fold -7 mod 3 (signed)
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSMod %long %long_n7 %long_3\n" + "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2ll),
- // Test case 12: fold -7 rem 3 (signed)
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSRem %long %long_n7 %long_3\n" + "OpReturn\n" +
- "OpFunctionEnd",
- 2, -1ll),
- // Test case 13: fold long(-24)
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSConvert %long %int_n24\n" + "OpReturn\n" +
- "OpFunctionEnd",
- 2, -24ll),
- // Test case 14: fold long(-24)
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" + "%2 = OpSConvert %long %int_10\n" +
- "OpReturn\n" + "OpFunctionEnd",
- 2, 10ll),
- // Test case 15: fold long(-24(short)).
- // The upper bits should be cleared. So 0xFFFFFFE8 should become
- // 0x000000000000FFE8.
- InstructionFoldingCase<uint64_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" + "%2 = OpUConvert %ulong %short_n5\n" +
- "OpReturn\n" + "OpFunctionEnd",
- 2, 65531ull)));
- using UIntVectorInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<std::vector<uint32_t>>>;
- TEST_P(UIntVectorInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- CheckForExpectedVectorConstant(
- inst, tc.expected_result,
- [](const analysis::Constant* c) { return c->GetU32(); });
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(TestCase, UIntVectorInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold 0*n
- InstructionFoldingCase<std::vector<uint32_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpVectorShuffle %v2int %v2int_2_2 %v2int_2_3 0 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {2,3}),
- InstructionFoldingCase<std::vector<uint32_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpVectorShuffle %v2int %v2int_null %v2int_2_3 0 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {0,3}),
- // Test case 4: fold bit-cast int -24 to unsigned int
- InstructionFoldingCase<std::vector<uint32_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpBitcast %v2uint %v2int_min_max\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {2147483648, 2147483647}),
- // Test case 5: fold SNegate vector of uint
- InstructionFoldingCase<std::vector<uint32_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSNegate %v2uint %v2uint_0x3f800000_0xbf800000\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {static_cast<uint32_t>(-0x3f800000), static_cast<uint32_t>(-0xbf800000)}),
- // Test case 6: fold vector components of uint (including integer overflow)
- InstructionFoldingCase<std::vector<uint32_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpIAdd %v2uint %v2uint_0x3f800000_0xbf800000 %v2uint_0x3f800000_0xbf800000\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {0x7f000000u, 0x7f000000u}),
- // Test case 6: fold vector components of uint
- InstructionFoldingCase<std::vector<uint32_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSConvert %v2int %v2short_2_n5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {2,static_cast<uint32_t>(-5)}),
- // Test case 6: fold vector components of uint (incuding integer overflow)
- InstructionFoldingCase<std::vector<uint32_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpUConvert %v2uint %v2short_2_n5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {2,65531})
- ));
- // clang-format on
- using IntVectorInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<std::vector<int32_t>>>;
- TEST_P(IntVectorInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- CheckForExpectedVectorConstant(
- inst, tc.expected_result,
- [](const analysis::Constant* c) { return c->GetS32(); });
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(TestCase, IntVectorInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold negate of a vector
- InstructionFoldingCase<std::vector<int32_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSNegate %v2int %v2int_2_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {-2, -3}),
- // Test case 1: fold negate of a vector containing negative values.
- InstructionFoldingCase<std::vector<int32_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSNegate %v2int %v2int_n1_n24\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {1, 24}),
- // Test case 2: fold negate of a vector at the limits
- InstructionFoldingCase<std::vector<int32_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSNegate %v2int %v2int_min_max\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {INT_MIN, -INT_MAX}),
- // Test case 3: fold vector components of int
- InstructionFoldingCase<std::vector<int32_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpIMul %v2int %v2int_2_3 %v2int_2_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {4,9})
- ));
- // clang-format on
- using LongIntVectorInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<std::vector<uint64_t>>>;
- TEST_P(LongIntVectorInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- CheckForExpectedVectorConstant(
- inst, tc.expected_result,
- [](const analysis::Constant* c) { return c->GetU64(); });
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(TestCase, LongIntVectorInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold {2,2} + {2,3} (Testing that the vector logic works
- // correctly. Scalar tests will check that the 64-bit values are correctly
- // folded.)
- InstructionFoldingCase<std::vector<uint64_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpIAdd %v2long %v2long_2_2 %v2long_2_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {4,5}),
- // Test case 0: fold {2,2} / {2,3} (Testing that the vector logic works
- // correctly. Scalar tests will check that the 64-bit values are correctly
- // folded.)
- InstructionFoldingCase<std::vector<uint64_t>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSDiv %v2long %v2long_2_2 %v2long_2_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {1,0})
- ));
- // clang-format on
- using DoubleVectorInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<std::vector<double>>>;
- TEST_P(DoubleVectorInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- CheckForExpectedVectorConstant(
- inst, tc.expected_result,
- [](const analysis::Constant* c) { return c->GetDouble(); });
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(TestCase, DoubleVectorInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: bit-cast int {0x3FF00000,0x00000000,0xC05FD666,0x66666666}
- // to double vector
- InstructionFoldingCase<std::vector<double>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %v2double %v4int_0x3FF00000_0x00000000_0xC05FD666_0x66666666\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {1.0,-127.35}),
- // Test case 1: OpVectorTimesMatrix Non-Zero Zero {{0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}} {1.0, 2.0, 3.0, 4.0} {0.0, 0.0, 0.0, 0.0}
- InstructionFoldingCase<std::vector<double>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesMatrix %v4double %v4double_1_2_3_4 %mat4v4double_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {0.0,0.0,0.0,0.0}),
- // Test case 2: OpVectorTimesMatrix Zero Non-Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {0.0, 0.0, 0.0, 0.0} {0.0, 0.0, 0.0, 0.0}
- InstructionFoldingCase<std::vector<double>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesMatrix %v4double %v4double_null %mat4v4double_1_2_3_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {0.0,0.0,0.0,0.0}),
- // Test case 3: OpVectorTimesMatrix Non-Zero Non-Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {1.0, 2.0, 3.0, 4.0} {30.0, 30.0, 30.0, 30.0}
- InstructionFoldingCase<std::vector<double>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesMatrix %v4double %v4double_1_2_3_4 %mat4v4double_1_2_3_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {30.0,30.0,30.0,30.0}),
- // Test case 4: OpVectorTimesMatrix Non-Zero Non-Zero {{1.0, 2.0, 3.0, 4.0}, Null, {1.0, 2.0, 3.0, 4.0}, Null} {1.0, 2.0, 3.0, 4.0} {30.0, 0.0, 30.0, 0.0}
- InstructionFoldingCase<std::vector<double>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesMatrix %v4double %v4double_1_2_3_4 %mat4v4double_1_2_3_4_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {30.0,0.0,30.0,0.0}),
- // Test case 5: OpMatrixTimesVector Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}} {0.0, 0.0, 0.0, 0.0}
- InstructionFoldingCase<std::vector<double>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpMatrixTimesVector %v4double %mat4v4double_null %v4double_1_2_3_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {0.0,0.0,0.0,0.0}),
- // Test case 6: OpMatrixTimesVector Non-Zero Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {0.0, 0.0, 0.0, 0.0} {0.0, 0.0, 0.0, 0.0}
- InstructionFoldingCase<std::vector<double>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpMatrixTimesVector %v4double %mat4v4double_1_2_3_4 %v4double_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {0.0,0.0,0.0,0.0}),
- // Test case 7: OpMatrixTimesVector Non-Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {10.0, 20.0, 30.0, 40.0}
- InstructionFoldingCase<std::vector<double>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpMatrixTimesVector %v4double %mat4v4double_1_2_3_4 %v4double_1_2_3_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {10.0,20.0,30.0,40.0}),
- // Test case 8: OpMatrixTimesVector Non-Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{1.0, 2.0, 3.0, 4.0}, Null, {1.0, 2.0, 3.0, 4.0}, Null} {10.0, 20.0, 30.0, 40.0}
- InstructionFoldingCase<std::vector<double>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpMatrixTimesVector %v4double %mat4v4double_1_2_3_4_null %v4double_1_2_3_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {4.0,8.0,12.0,16.0})
- ));
- using FloatVectorInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<std::vector<float>>>;
- TEST_P(FloatVectorInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) = FoldInstruction(tc.test_body, tc.id_to_fold,SPV_ENV_UNIVERSAL_1_1);
- CheckForExpectedVectorConstant(inst, tc.expected_result, [](const analysis::Constant* c){ return c->GetFloat();});
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(TestCase, FloatVectorInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: FMix {2.0, 2.0}, {2.0, 3.0} {0.2,0.5}
- InstructionFoldingCase<std::vector<float>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %v2float %1 FMix %v2float_2_3 %v2float_0_0 %v2float_0p2_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {1.6f,1.5f}),
- // Test case 1: bit-cast unsigned int vector {0x3f800000, 0xbf800000} to
- // float vector
- InstructionFoldingCase<std::vector<float>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %v2float %v2uint_0x3f800000_0xbf800000\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {1.0f,-1.0f}),
- // Test case 2: bit-cast long int 0xbf8000003f800000 to float vector
- InstructionFoldingCase<std::vector<float>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpBitcast %v2float %long_0xbf8000003f800000\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {1.0f,-1.0f}),
- // Test case 3: OpVectorTimesMatrix Non-Zero Zero {{0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}} {1.0, 2.0, 3.0, 4.0} {0.0, 0.0, 0.0, 0.0}
- InstructionFoldingCase<std::vector<float>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesMatrix %v4float %v4float_1_2_3_4 %mat4v4float_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {0.0f,0.0f,0.0f,0.0f}),
- // Test case 4: OpVectorTimesMatrix Non-Zero Non-Zero {{1.0, 2.0, 3.0, 4.0}, Null, {1.0, 2.0, 3.0, 4.0}, Null} {1.0, 2.0, 3.0, 4.0} {30.0, 0.0, 30.0, 0.0}
- InstructionFoldingCase<std::vector<float>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesMatrix %v4float %v4float_1_2_3_4 %mat4v4float_1_2_3_4_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {30.0,0.0,30.0,0.0}),
- // Test case 5: OpVectorTimesMatrix Zero Non-Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {0.0, 0.0, 0.0, 0.0} {0.0, 0.0, 0.0, 0.0}
- InstructionFoldingCase<std::vector<float>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesMatrix %v4float %v4float_null %mat4v4float_1_2_3_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {0.0f,0.0f,0.0f,0.0f}),
- // Test case 6: OpVectorTimesMatrix Non-Zero Non-Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {1.0, 2.0, 3.0, 4.0} {30.0, 30.0, 30.0, 30.0}
- InstructionFoldingCase<std::vector<float>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesMatrix %v4float %v4float_1_2_3_4 %mat4v4float_1_2_3_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {30.0f,30.0f,30.0f,30.0f}),
- // Test case 7: OpMatrixTimesVector Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}} {0.0, 0.0, 0.0, 0.0}
- InstructionFoldingCase<std::vector<float>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpMatrixTimesVector %v4float %mat4v4float_null %v4float_1_2_3_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {0.0f,0.0f,0.0f,0.0f}),
- // Test case 8: OpMatrixTimesVector Non-Zero Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {0.0, 0.0, 0.0, 0.0} {0.0, 0.0, 0.0, 0.0}
- InstructionFoldingCase<std::vector<float>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpMatrixTimesVector %v4float %mat4v4float_1_2_3_4 %v4float_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {0.0f,0.0f,0.0f,0.0f}),
- // Test case 9: OpMatrixTimesVector Non-Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {10.0, 20.0, 30.0, 40.0}
- InstructionFoldingCase<std::vector<float>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpMatrixTimesVector %v4float %mat4v4float_1_2_3_4 %v4float_1_2_3_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {10.0f,20.0f,30.0f,40.0f}),
- // Test case 10: OpMatrixTimesVector Non-Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{1.0, 2.0, 3.0, 4.0}, Null, {1.0, 2.0, 3.0, 4.0}, Null} {10.0, 20.0, 30.0, 40.0}
- InstructionFoldingCase<std::vector<float>>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpMatrixTimesVector %v4float %mat4v4float_1_2_3_4_null %v4float_1_2_3_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {4.0,8.0,12.0,16.0})
- ));
- // clang-format on
- using FloatMatrixInstructionFoldingTest = ::testing::TestWithParam<
- InstructionFoldingCase<std::vector<std::vector<float>>>>;
- TEST_P(FloatMatrixInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
- if (inst->opcode() == spv::Op::OpCopyObject) {
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- analysis::ConstantManager* const_mgr = context->get_constant_mgr();
- const analysis::Constant* result = const_mgr->GetConstantFromInst(inst);
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- std::vector<const analysis::Constant*> matrix =
- result->AsMatrixConstant()->GetComponents();
- EXPECT_EQ(matrix.size(), tc.expected_result.size());
- for (size_t c = 0; c < matrix.size(); c++) {
- if (matrix[c]->AsNullConstant() != nullptr) {
- matrix[c] = const_mgr->GetNullCompositeConstant(matrix[c]->type());
- }
- const analysis::VectorConstant* column_const =
- matrix[c]->AsVectorConstant();
- ASSERT_NE(column_const, nullptr);
- const std::vector<const analysis::Constant*>& column =
- column_const->GetComponents();
- EXPECT_EQ(column.size(), tc.expected_result[c].size());
- for (size_t r = 0; r < column.size(); r++) {
- EXPECT_EQ(tc.expected_result[c][r], column[r]->GetFloat());
- }
- }
- }
- }
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(TestCase, FloatMatrixInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: OpTranspose square null matrix
- InstructionFoldingCase<std::vector<std::vector<float>>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpTranspose %mat4v4float %mat4v4float_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {{0.0f, 0.0f, 0.0f, 0.0f},{0.0f, 0.0f, 0.0f, 0.0f},{0.0f, 0.0f, 0.0f, 0.0f},{0.0f, 0.0f, 0.0f, 0.0f}}),
- // Test case 1: OpTranspose rectangular null matrix
- InstructionFoldingCase<std::vector<std::vector<float>>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpTranspose %mat4v2float %mat2v4float_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {{0.0f, 0.0f},{0.0f, 0.0f},{0.0f, 0.0f},{0.0f, 0.0f}}),
- InstructionFoldingCase<std::vector<std::vector<float>>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpTranspose %mat4v4float %mat4v4float_1_2_3_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {{1.0f, 1.0f, 1.0f, 1.0f},{2.0f, 2.0f, 2.0f, 2.0f},{3.0f, 3.0f, 3.0f, 3.0f},{4.0f, 4.0f, 4.0f, 4.0f}})
- ));
- // clang-format on
- using BooleanInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<bool>>;
- TEST_P(BooleanInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- CheckForExpectedScalarConstant(
- inst, tc.expected_result,
- [](const analysis::Constant* c) { return c->AsBoolConstant()->value(); });
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(TestCase, BooleanInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold true || n
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_bool Function\n" +
- "%load = OpLoad %bool %n\n" +
- "%2 = OpLogicalOr %bool %true %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 1: fold n || true
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_bool Function\n" +
- "%load = OpLoad %bool %n\n" +
- "%2 = OpLogicalOr %bool %load %true\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 2: fold false && n
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_bool Function\n" +
- "%load = OpLoad %bool %n\n" +
- "%2 = OpLogicalAnd %bool %false %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 3: fold n && false
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_bool Function\n" +
- "%load = OpLoad %bool %n\n" +
- "%2 = OpLogicalAnd %bool %load %false\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 4: fold n < 0 (unsigned)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpULessThan %bool %load %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 5: fold UINT_MAX < n (unsigned)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpULessThan %bool %uint_max %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 6: fold INT_MAX < n (signed)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSLessThan %bool %int_max %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 7: fold n < INT_MIN (signed)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSLessThan %bool %load %int_min\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 8: fold 0 > n (unsigned)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpUGreaterThan %bool %uint_0 %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 9: fold n > UINT_MAX (unsigned)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpUGreaterThan %bool %load %uint_max\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 10: fold n > INT_MAX (signed)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSGreaterThan %bool %load %int_max\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 11: fold INT_MIN > n (signed)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpSGreaterThan %bool %int_min %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 12: fold 0 <= n (unsigned)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpULessThanEqual %bool %uint_0 %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 13: fold n <= UINT_MAX (unsigned)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpULessThanEqual %bool %load %uint_max\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 14: fold INT_MIN <= n (signed)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSLessThanEqual %bool %int_min %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 15: fold n <= INT_MAX (signed)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSLessThanEqual %bool %load %int_max\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 16: fold n >= 0 (unsigned)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpUGreaterThanEqual %bool %load %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 17: fold UINT_MAX >= n (unsigned)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load = OpLoad %uint %n\n" +
- "%2 = OpUGreaterThanEqual %bool %uint_max %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 18: fold n >= INT_MIN (signed)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSGreaterThanEqual %bool %load %int_min\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 19: fold INT_MAX >= n (signed)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSGreaterThanEqual %bool %int_max %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true)
- ));
- INSTANTIATE_TEST_SUITE_P(FClampAndCmpLHS, BooleanInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold 0.0 > clamp(n, 0.0, 1.0)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_0 %float_1\n" +
- "%2 = OpFOrdGreaterThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 1: fold 0.0 > clamp(n, -1.0, -1.0)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_n1\n" +
- "%2 = OpFOrdGreaterThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 2: fold 0.0 >= clamp(n, 1, 2)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_2\n" +
- "%2 = OpFOrdGreaterThanEqual %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 3: fold 0.0 >= clamp(n, -1.0, 0.0)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_0\n" +
- "%2 = OpFOrdGreaterThanEqual %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 4: fold 0.0 <= clamp(n, 0.0, 1.0)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_0 %float_1\n" +
- "%2 = OpFOrdLessThanEqual %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 5: fold 0.0 <= clamp(n, -1.0, -1.0)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_n1\n" +
- "%2 = OpFOrdLessThanEqual %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 6: fold 0.0 < clamp(n, 1, 2)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_2\n" +
- "%2 = OpFOrdLessThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 7: fold 0.0 < clamp(n, -1.0, 0.0)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_0\n" +
- "%2 = OpFOrdLessThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 8: fold 0.0 > clamp(n, 0.0, 1.0)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_0 %float_1\n" +
- "%2 = OpFUnordGreaterThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 9: fold 0.0 > clamp(n, -1.0, -1.0)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_n1\n" +
- "%2 = OpFUnordGreaterThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 10: fold 0.0 >= clamp(n, 1, 2)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_2\n" +
- "%2 = OpFUnordGreaterThanEqual %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 11: fold 0.0 >= clamp(n, -1.0, 0.0)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_0\n" +
- "%2 = OpFUnordGreaterThanEqual %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 12: fold 0.0 <= clamp(n, 0.0, 1.0)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_0 %float_1\n" +
- "%2 = OpFUnordLessThanEqual %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 13: fold 0.0 <= clamp(n, -1.0, -1.0)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_n1\n" +
- "%2 = OpFUnordLessThanEqual %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 14: fold 0.0 < clamp(n, 1, 2)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_2\n" +
- "%2 = OpFUnordLessThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 15: fold 0.0 < clamp(n, -1.0, 0.0)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_0\n" +
- "%2 = OpFUnordLessThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false)
- ));
- INSTANTIATE_TEST_SUITE_P(FClampAndCmpRHS, BooleanInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold clamp(n, 0.0, 1.0) > 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_0 %float_1\n" +
- "%2 = OpFOrdGreaterThan %bool %clamp %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 1: fold clamp(n, 1.0, 1.0) > 0.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_1\n" +
- "%2 = OpFOrdGreaterThan %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 2: fold clamp(n, 1, 2) >= 0.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_2\n" +
- "%2 = OpFOrdGreaterThanEqual %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 3: fold clamp(n, 1.0, 2.0) >= 3.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_2\n" +
- "%2 = OpFOrdGreaterThanEqual %bool %clamp %float_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 4: fold clamp(n, 0.0, 1.0) <= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_0 %float_1\n" +
- "%2 = OpFOrdLessThanEqual %bool %clamp %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 5: fold clamp(n, 1.0, 2.0) <= 0.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_2\n" +
- "%2 = OpFOrdLessThanEqual %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 6: fold clamp(n, 1, 2) < 3
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_2\n" +
- "%2 = OpFOrdLessThan %bool %clamp %float_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 7: fold clamp(n, -1.0, 0.0) < -1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_0\n" +
- "%2 = OpFOrdLessThan %bool %clamp %float_n1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 8: fold clamp(n, 0.0, 1.0) > 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_0 %float_1\n" +
- "%2 = OpFUnordGreaterThan %bool %clamp %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 9: fold clamp(n, 1.0, 2.0) > 0.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_2\n" +
- "%2 = OpFUnordGreaterThan %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 10: fold clamp(n, 1, 2) >= 3.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_2\n" +
- "%2 = OpFUnordGreaterThanEqual %bool %clamp %float_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 11: fold clamp(n, -1.0, 0.0) >= -1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_0\n" +
- "%2 = OpFUnordGreaterThanEqual %bool %clamp %float_n1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 12: fold clamp(n, 0.0, 1.0) <= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_0 %float_1\n" +
- "%2 = OpFUnordLessThanEqual %bool %clamp %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 13: fold clamp(n, 1.0, 1.0) <= 0.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_1\n" +
- "%2 = OpFUnordLessThanEqual %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 14: fold clamp(n, 1, 2) < 3
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_1 %float_2\n" +
- "%2 = OpFUnordLessThan %bool %clamp %float_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 15: fold clamp(n, -1.0, 0.0) < -1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_0\n" +
- "%2 = OpFUnordLessThan %bool %clamp %float_n1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 16: fold clamp(n, -1.0, 0.0) < -1.0 (one test for double)
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%ld = OpLoad %double %n\n" +
- "%clamp = OpExtInst %double %1 FClamp %ld %double_n1 %double_0\n" +
- "%2 = OpFUnordLessThan %bool %clamp %double_n1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false)
- ));
- // clang-format on
- using FloatInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<float>>;
- TEST_P(FloatInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- CheckForExpectedScalarConstant(inst, tc.expected_result,
- [](const analysis::Constant* c) {
- return c->AsFloatConstant()->GetFloatValue();
- });
- }
- // Not testing NaNs because there are no expectations concerning NaNs according
- // to the "Precision and Operation of SPIR-V Instructions" section of the Vulkan
- // specification.
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(FloatConstantFoldingTest, FloatInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Fold 2.0 - 1.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFSub %float %float_2 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 1: Fold 2.0 + 1.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFAdd %float %float_2 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3.0),
- // Test case 2: Fold 3.0 * 2.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFMul %float %float_3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 6.0),
- // Test case 3: Fold 1.0 / 2.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %float %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.5),
- // Test case 4: Fold 1.0 / 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %float %float_1 %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<float>::infinity()),
- // Test case 5: Fold -1.0 / 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %float %float_n1 %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -std::numeric_limits<float>::infinity()),
- // Test case 6: Fold (2.0, 3.0) dot (2.0, 0.5)
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpDot %float %v2float_2_3 %v2float_2_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 5.5f),
- // Test case 7: Fold (0.0, 0.0) dot v
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%v = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %v\n" +
- "%3 = OpDot %float %v2float_0_0 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0.0f),
- // Test case 8: Fold v dot (0.0, 0.0)
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%v = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %v\n" +
- "%3 = OpDot %float %2 %v2float_0_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0.0f),
- // Test case 9: Fold Null dot v
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%v = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %v\n" +
- "%3 = OpDot %float %v2float_null %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0.0f),
- // Test case 10: Fold v dot Null
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%v = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %v\n" +
- "%3 = OpDot %float %2 %v2float_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0.0f),
- // Test case 11: Fold -2.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFNegate %float %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -2),
- // Test case 12: QuantizeToF16 1.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 13: QuantizeToF16 positive non exact
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_2049\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2048),
- // Test case 14: QuantizeToF16 negative non exact
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_n2049\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -2048),
- // Test case 15: QuantizeToF16 large positive
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_1e16\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<float>::infinity()),
- // Test case 16: QuantizeToF16 large negative
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_n1e16\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -std::numeric_limits<float>::infinity()),
- // Test case 17: QuantizeToF16 small positive
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_1en16\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 18: QuantizeToF16 small negative
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_n1en16\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 19: QuantizeToF16 nan
- InstructionFoldingCase<float>(
- HeaderWithNaN() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_nan\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<float>::quiet_NaN()),
- // Test case 20: FMix 1.0 4.0 0.2
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FMix %float_1 %float_4 %float_0p2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.6f),
- // Test case 21: FMin 1.0 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FMin %float_1 %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0f),
- // Test case 22: FMin 4.0 0.2
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FMin %float_4 %float_0p2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.2f),
- // Test case 23: FMax 1.0 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FMax %float_1 %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4.0f),
- // Test case 24: FMax 1.0 0.2
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FMax %float_1 %float_0p2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0f),
- // Test case 25: FClamp 1.0 0.2 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FClamp %float_1 %float_0p2 %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0f),
- // Test case 26: FClamp 0.2 2.0 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FClamp %float_0p2 %float_2 %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0f),
- // Test case 27: FClamp 2049.0 2.0 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FClamp %float_2049 %float_2 %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4.0f),
- // Test case 28: FClamp 1.0 2.0 x
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %float\n" +
- "%2 = OpExtInst %float %1 FClamp %float_1 %float_2 %undef\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0),
- // Test case 29: FClamp 1.0 x 0.5
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %float\n" +
- "%2 = OpExtInst %float %1 FClamp %float_1 %undef %float_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.5),
- // Test case 30: Sin 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Sin %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 31: Cos 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Cos %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 32: Tan 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Tan %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 33: Asin 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Asin %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 34: Acos 1.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Acos %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 35: Atan 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Atan %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 36: Exp 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Exp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 37: Log 1.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Log %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 38: Exp2 2.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Exp2 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4.0),
- // Test case 39: Log2 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Log2 %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0),
- // Test case 40: Sqrt 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Sqrt %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0),
- // Test case 41: Atan2 0.0 1.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Atan2 %float_0 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 42: Pow 2.0 3.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Pow %float_2 %float_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 8.0),
- // Test case 43: Fold 1.0 / -0.0.
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %float %float_1 %float_n0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -std::numeric_limits<float>::infinity()),
- // Test case 44: Fold -1.0 / -0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %float %float_n1 %float_n0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<float>::infinity()),
- // Test case 45: Fold 0.0 / 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %float %float_0 %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<float>::quiet_NaN()),
- // Test case 46: Fold 0.0 / -0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %float %float_0 %float_n0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<float>::quiet_NaN())
- ));
- // clang-format on
- using DoubleInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<double>>;
- TEST_P(DoubleInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- CheckForExpectedScalarConstant(
- inst, tc.expected_result, [](const analysis::Constant* c) {
- return c->AsFloatConstant()->GetDoubleValue();
- });
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(DoubleConstantFoldingTest, DoubleInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Fold 2.0 - 1.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFSub %double %double_2 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 1: Fold 2.0 + 1.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFAdd %double %double_2 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3.0),
- // Test case 2: Fold 3.0 * 2.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFMul %double %double_3 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 6.0),
- // Test case 3: Fold 1.0 / 2.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %double %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.5),
- // Test case 4: Fold 1.0 / 0.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %double %double_1 %double_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<double>::infinity()),
- // Test case 5: Fold -1.0 / 0.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %double %double_n1 %double_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -std::numeric_limits<double>::infinity()),
- // Test case 6: Fold (2.0, 3.0) dot (2.0, 0.5)
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpDot %double %v2double_2_3 %v2double_2_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 5.5f),
- // Test case 7: Fold (0.0, 0.0) dot v
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%v = OpVariable %_ptr_v2double Function\n" +
- "%2 = OpLoad %v2double %v\n" +
- "%3 = OpDot %double %v2double_0_0 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0.0f),
- // Test case 8: Fold v dot (0.0, 0.0)
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%v = OpVariable %_ptr_v2double Function\n" +
- "%2 = OpLoad %v2double %v\n" +
- "%3 = OpDot %double %2 %v2double_0_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0.0f),
- // Test case 9: Fold Null dot v
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%v = OpVariable %_ptr_v2double Function\n" +
- "%2 = OpLoad %v2double %v\n" +
- "%3 = OpDot %double %v2double_null %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0.0f),
- // Test case 10: Fold v dot Null
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%v = OpVariable %_ptr_v2double Function\n" +
- "%2 = OpLoad %v2double %v\n" +
- "%3 = OpDot %double %2 %v2double_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0.0f),
- // Test case 11: Fold -2.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFNegate %double %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -2),
- // Test case 12: FMin 1.0 4.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FMin %double_1 %double_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 13: FMin 4.0 0.2
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FMin %double_4 %double_0p2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.2),
- // Test case 14: FMax 1.0 4.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FMax %double_1 %double_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4.0),
- // Test case 15: FMax 1.0 0.2
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FMax %double_1 %double_0p2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 16: FClamp 1.0 0.2 4.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FClamp %double_1 %double_0p2 %double_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 17: FClamp 0.2 2.0 4.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FClamp %double_0p2 %double_2 %double_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0),
- // Test case 18: FClamp 5.0 2.0 4.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FClamp %double_5 %double_2 %double_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4.0),
- // Test case 19: FClamp 1.0 2.0 x
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %double\n" +
- "%2 = OpExtInst %double %1 FClamp %double_1 %double_2 %undef\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0),
- // Test case 20: FClamp 1.0 x 0.5
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %double\n" +
- "%2 = OpExtInst %double %1 FClamp %double_1 %undef %double_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.5),
- // Test case 21: Sqrt 4.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %double\n" +
- "%2 = OpExtInst %double %1 Sqrt %double_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0),
- // Test case 22: Pow 2.0 3.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %double\n" +
- "%2 = OpExtInst %double %1 Pow %double_2 %double_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 8.0),
- // Test case 23: Fold 1.0 / -0.0.
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %double %double_1 %double_n0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -std::numeric_limits<double>::infinity()),
- // Test case 24: Fold -1.0 / -0.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %double %double_n1 %double_n0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<double>::infinity()),
- // Test case 25: Fold 0.0 / 0.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %double %double_0 %double_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<double>::quiet_NaN()),
- // Test case 26: Fold 0.0 / -0.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %double %double_0 %double_n0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<double>::quiet_NaN())
- ));
- // clang-format on
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(DoubleOrderedCompareConstantFoldingTest, BooleanInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold 1.0 == 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdEqual %bool %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 1: fold 1.0 != 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdNotEqual %bool %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 2: fold 1.0 < 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdLessThan %bool %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 3: fold 1.0 > 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdGreaterThan %bool %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 4: fold 1.0 <= 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdLessThanEqual %bool %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 5: fold 1.0 >= 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdGreaterThanEqual %bool %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 6: fold 1.0 == 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdEqual %bool %double_1 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 7: fold 1.0 != 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdNotEqual %bool %double_1 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 8: fold 1.0 < 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdLessThan %bool %double_1 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 9: fold 1.0 > 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdGreaterThan %bool %double_1 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 10: fold 1.0 <= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdLessThanEqual %bool %double_1 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 11: fold 1.0 >= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdGreaterThanEqual %bool %double_1 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 12: fold 2.0 < 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdLessThan %bool %double_2 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 13: fold 2.0 > 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdGreaterThan %bool %double_2 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 14: fold 2.0 <= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdLessThanEqual %bool %double_2 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 15: fold 2.0 >= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdGreaterThanEqual %bool %double_2 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true)
- ));
- INSTANTIATE_TEST_SUITE_P(DoubleUnorderedCompareConstantFoldingTest, BooleanInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold 1.0 == 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordEqual %bool %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 1: fold 1.0 != 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordNotEqual %bool %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 2: fold 1.0 < 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordLessThan %bool %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 3: fold 1.0 > 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordGreaterThan %bool %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 4: fold 1.0 <= 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordLessThanEqual %bool %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 5: fold 1.0 >= 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordGreaterThanEqual %bool %double_1 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 6: fold 1.0 == 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordEqual %bool %double_1 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 7: fold 1.0 != 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordNotEqual %bool %double_1 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 8: fold 1.0 < 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordLessThan %bool %double_1 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 9: fold 1.0 > 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordGreaterThan %bool %double_1 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 10: fold 1.0 <= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordLessThanEqual %bool %double_1 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 11: fold 1.0 >= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordGreaterThanEqual %bool %double_1 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 12: fold 2.0 < 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordLessThan %bool %double_2 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 13: fold 2.0 > 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordGreaterThan %bool %double_2 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 14: fold 2.0 <= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordLessThanEqual %bool %double_2 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 15: fold 2.0 >= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordGreaterThanEqual %bool %double_2 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true)
- ));
- INSTANTIATE_TEST_SUITE_P(FloatOrderedCompareConstantFoldingTest, BooleanInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold 1.0 == 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdEqual %bool %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 1: fold 1.0 != 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdNotEqual %bool %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 2: fold 1.0 < 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdLessThan %bool %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 3: fold 1.0 > 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdGreaterThan %bool %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 4: fold 1.0 <= 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdLessThanEqual %bool %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 5: fold 1.0 >= 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdGreaterThanEqual %bool %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 6: fold 1.0 == 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdEqual %bool %float_1 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 7: fold 1.0 != 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdNotEqual %bool %float_1 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 8: fold 1.0 < 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdLessThan %bool %float_1 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 9: fold 1.0 > 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdGreaterThan %bool %float_1 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 10: fold 1.0 <= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdLessThanEqual %bool %float_1 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 11: fold 1.0 >= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdGreaterThanEqual %bool %float_1 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 12: fold 2.0 < 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdLessThan %bool %float_2 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 13: fold 2.0 > 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdGreaterThan %bool %float_2 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 14: fold 2.0 <= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdLessThanEqual %bool %float_2 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 15: fold 2.0 >= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdGreaterThanEqual %bool %float_2 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true)
- ));
- INSTANTIATE_TEST_SUITE_P(FloatUnorderedCompareConstantFoldingTest, BooleanInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold 1.0 == 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordEqual %bool %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 1: fold 1.0 != 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordNotEqual %bool %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 2: fold 1.0 < 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordLessThan %bool %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 3: fold 1.0 > 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordGreaterThan %bool %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 4: fold 1.0 <= 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordLessThanEqual %bool %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 5: fold 1.0 >= 2.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordGreaterThanEqual %bool %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 6: fold 1.0 == 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordEqual %bool %float_1 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 7: fold 1.0 != 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordNotEqual %bool %float_1 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 8: fold 1.0 < 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordLessThan %bool %float_1 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 9: fold 1.0 > 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordGreaterThan %bool %float_1 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 10: fold 1.0 <= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordLessThanEqual %bool %float_1 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 11: fold 1.0 >= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordGreaterThanEqual %bool %float_1 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 12: fold 2.0 < 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordLessThan %bool %float_2 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 13: fold 2.0 > 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordGreaterThan %bool %float_2 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 14: fold 2.0 <= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordLessThanEqual %bool %float_2 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 15: fold 2.0 >= 1.0
- InstructionFoldingCase<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordGreaterThanEqual %bool %float_2 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true)
- ));
- INSTANTIATE_TEST_SUITE_P(DoubleNaNCompareConstantFoldingTest, BooleanInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold NaN == 0 (ord)
- InstructionFoldingCase<bool>(
- HeaderWithNaN() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdEqual %bool %double_nan %double_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 1: fold NaN == NaN (unord)
- InstructionFoldingCase<bool>(
- HeaderWithNaN() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordEqual %bool %double_nan %double_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 2: fold NaN != NaN (ord)
- InstructionFoldingCase<bool>(
- HeaderWithNaN() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdNotEqual %bool %double_nan %double_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 3: fold NaN != NaN (unord)
- InstructionFoldingCase<bool>(
- HeaderWithNaN() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordNotEqual %bool %double_nan %double_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true)
- ));
- INSTANTIATE_TEST_SUITE_P(FloatNaNCompareConstantFoldingTest, BooleanInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold NaN == 0 (ord)
- InstructionFoldingCase<bool>(
- HeaderWithNaN() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdEqual %bool %float_nan %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 1: fold NaN == NaN (unord)
- InstructionFoldingCase<bool>(
- HeaderWithNaN() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordEqual %bool %float_nan %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 2: fold NaN != NaN (ord)
- InstructionFoldingCase<bool>(
- HeaderWithNaN() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFOrdNotEqual %bool %float_nan %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, false),
- // Test case 3: fold NaN != NaN (unord)
- InstructionFoldingCase<bool>(
- HeaderWithNaN() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFUnordNotEqual %bool %float_nan %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true)
- ));
- // clang-format on
- template <class ResultType>
- struct InstructionFoldingCaseWithMap {
- InstructionFoldingCaseWithMap(const std::string& tb, uint32_t id,
- ResultType result,
- std::function<uint32_t(uint32_t)> map)
- : test_body(tb), id_to_fold(id), expected_result(result), id_map(map) {}
- std::string test_body;
- uint32_t id_to_fold;
- ResultType expected_result;
- std::function<uint32_t(uint32_t)> id_map;
- };
- using IntegerInstructionFoldingTestWithMap =
- ::testing::TestWithParam<InstructionFoldingCaseWithMap<uint32_t>>;
- TEST_P(IntegerInstructionFoldingTestWithMap, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- GetInstructionToFold(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_5);
- inst = context->get_instruction_folder().FoldInstructionToConstant(inst,
- tc.id_map);
- EXPECT_NE(inst, nullptr);
- CheckForExpectedScalarConstant(inst, tc.expected_result,
- [](const analysis::Constant* c) {
- return c->AsIntConstant()->GetU32BitValue();
- });
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTestWithMap,
- ::testing::Values(
- // Test case 0: fold %3 = 0; %3 * n
- InstructionFoldingCaseWithMap<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%3 = OpCopyObject %int %int_0\n"
- "%2 = OpIMul %int %3 %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0, [](uint32_t id) {return (id == 3 ? INT_0_ID : id);})
- ));
- // clang-format on
- using BooleanInstructionFoldingTestWithMap =
- ::testing::TestWithParam<InstructionFoldingCaseWithMap<bool>>;
- TEST_P(BooleanInstructionFoldingTestWithMap, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- GetInstructionToFold(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_5);
- inst = context->get_instruction_folder().FoldInstructionToConstant(inst,
- tc.id_map);
- ASSERT_NE(inst, nullptr);
- CheckForExpectedScalarConstant(
- inst, tc.expected_result,
- [](const analysis::Constant* c) { return c->AsBoolConstant()->value(); });
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(TestCase, BooleanInstructionFoldingTestWithMap,
- ::testing::Values(
- // Test case 0: fold %3 = true; %3 || n
- InstructionFoldingCaseWithMap<bool>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_bool Function\n" +
- "%load = OpLoad %bool %n\n" +
- "%3 = OpCopyObject %bool %true\n" +
- "%2 = OpLogicalOr %bool %3 %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true, [](uint32_t id) {return (id == 3 ? TRUE_ID : id);})
- ));
- // clang-format on
- using GeneralInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<uint32_t>>;
- TEST_P(GeneralInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- EXPECT_TRUE((inst == nullptr) == (tc.expected_result == 0));
- if (inst != nullptr) {
- EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
- EXPECT_EQ(inst->GetSingleWordInOperand(0), tc.expected_result);
- }
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(IntegerArithmeticTestCases, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Don't fold n * m
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpIMul %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 1: Don't fold n / m (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpUDiv %uint %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 2: Don't fold n / m (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpSDiv %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 3: Don't fold n remainder m
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpSRem %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 4: Don't fold n % m (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpSMod %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 5: Don't fold n % m (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpUMod %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 6: Don't fold n << m
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpShiftRightLogical %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 7: Don't fold n >> m
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpShiftLeftLogical %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 8: Don't fold n | m
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpBitwiseOr %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 9: Don't fold n & m
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpBitwiseAnd %int %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 10: Don't fold n < m (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpULessThan %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 11: Don't fold n > m (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpUGreaterThan %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 12: Don't fold n <= m (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpULessThanEqual %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 13: Don't fold n >= m (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%m = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%load_m = OpLoad %uint %m\n" +
- "%2 = OpUGreaterThanEqual %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 14: Don't fold n < m (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpULessThan %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 15: Don't fold n > m (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpUGreaterThan %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 16: Don't fold n <= m (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpULessThanEqual %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 17: Don't fold n >= m (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%m = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%load_m = OpLoad %int %m\n" +
- "%2 = OpUGreaterThanEqual %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 18: Don't fold n || m
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_bool Function\n" +
- "%m = OpVariable %_ptr_bool Function\n" +
- "%load_n = OpLoad %bool %n\n" +
- "%load_m = OpLoad %bool %m\n" +
- "%2 = OpLogicalOr %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 19: Don't fold n && m
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_bool Function\n" +
- "%m = OpVariable %_ptr_bool Function\n" +
- "%load_n = OpLoad %bool %n\n" +
- "%load_m = OpLoad %bool %m\n" +
- "%2 = OpLogicalAnd %bool %load_n %load_m\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 20: Don't fold n * 3
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpIMul %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 21: Don't fold n / 3 (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpUDiv %uint %load_n %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 22: Don't fold n / 3 (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpSDiv %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 23: Don't fold n remainder 3
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpSRem %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 24: Don't fold n % 3 (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpSMod %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 25: Don't fold n % 3 (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpUMod %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 26: Don't fold n << 3
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpShiftRightLogical %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 27: Don't fold n >> 3
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpShiftLeftLogical %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 28: Don't fold n | 3
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpBitwiseOr %int %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 29: Don't fold n & 3
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpBitwiseAnd %uint %load_n %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 30: Don't fold n < 3 (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpULessThan %bool %load_n %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 31: Don't fold n > 3 (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpUGreaterThan %bool %load_n %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 32: Don't fold n <= 3 (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpULessThanEqual %bool %load_n %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 33: Don't fold n >= 3 (unsigned)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%load_n = OpLoad %uint %n\n" +
- "%2 = OpUGreaterThanEqual %bool %load_n %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 34: Don't fold n < 3 (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpULessThan %bool %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 35: Don't fold n > 3 (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpUGreaterThan %bool %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 36: Don't fold n <= 3 (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpULessThanEqual %bool %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 37: Don't fold n >= 3 (signed)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load_n = OpLoad %int %n\n" +
- "%2 = OpUGreaterThanEqual %bool %load_n %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 38: fold 1*n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%3 = OpLoad %int %n\n" +
- "%2 = OpIMul %int %int_1 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 39: fold n*1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%3 = OpLoad %int %n\n" +
- "%2 = OpIMul %int %3 %int_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 40: Don't fold comparisons of 64-bit types
- // (https://github.com/KhronosGroup/SPIRV-Tools/issues/3343).
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSLessThan %bool %long_0 %long_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 41: Don't fold OpSNegate for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSNegate %int_coop_matrix %undef_int_coop_matrix\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 42: Don't fold OpIAdd for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpIAdd %int_coop_matrix %undef_int_coop_matrix %undef_int_coop_matrix\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 43: Don't fold OpISub for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpISub %int_coop_matrix %undef_int_coop_matrix %undef_int_coop_matrix\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 44: Don't fold OpIMul for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpIMul %int_coop_matrix %undef_int_coop_matrix %undef_int_coop_matrix\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 45: Don't fold OpSDiv for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSDiv %int_coop_matrix %undef_int_coop_matrix %undef_int_coop_matrix\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 46: Don't fold OpUDiv for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpUDiv %uint_coop_matrix %undef_uint_coop_matrix %undef_uint_coop_matrix\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 47: Don't fold OpMatrixTimesScalar for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpMatrixTimesScalar %uint_coop_matrix %undef_uint_coop_matrix %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0)
- ));
- INSTANTIATE_TEST_SUITE_P(CompositeExtractFoldingTest, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold Insert feeding extract
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeInsert %v4int %2 %v4int_0_0_0_0 0\n" +
- "%4 = OpCompositeInsert %v4int %int_1 %3 1\n" +
- "%5 = OpCompositeInsert %v4int %int_1 %4 2\n" +
- "%6 = OpCompositeInsert %v4int %int_1 %5 3\n" +
- "%7 = OpCompositeExtract %int %6 0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 7, 2),
- // Test case 1: fold Composite construct feeding extract (position 0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeConstruct %v4int %2 %int_0 %int_0 %int_0\n" +
- "%4 = OpCompositeExtract %int %3 0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, 2),
- // Test case 2: fold Composite construct feeding extract (position 3)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeConstruct %v4int %2 %int_0 %int_0 %100\n" +
- "%4 = OpCompositeExtract %int %3 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, INT_0_ID),
- // Test case 3: fold Composite construct with vectors feeding extract (scalar element)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeConstruct %v2int %2 %int_0\n" +
- "%4 = OpCompositeConstruct %v4int %3 %int_0 %100\n" +
- "%5 = OpCompositeExtract %int %4 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, INT_0_ID),
- // Test case 4: fold Composite construct with vectors feeding extract (start of vector element)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeConstruct %v2int %2 %int_0\n" +
- "%4 = OpCompositeConstruct %v4int %3 %int_0 %100\n" +
- "%5 = OpCompositeExtract %int %4 0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, 2),
- // Test case 5: fold Composite construct with vectors feeding extract (middle of vector element)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeConstruct %v2int %int_0 %2\n" +
- "%4 = OpCompositeConstruct %v4int %3 %int_0 %100\n" +
- "%5 = OpCompositeExtract %int %4 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, 2),
- // Test case 6: fold Composite construct with multiple indices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeConstruct %v2int %int_0 %2\n" +
- "%4 = OpCompositeConstruct %struct_v2int_int_int %3 %int_0 %100\n" +
- "%5 = OpCompositeExtract %int %4 0 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, 2),
- // Test case 7: fold constant extract.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeExtract %int %102 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, INT_7_ID),
- // Test case 8: constant struct has OpUndef
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeExtract %int %struct_undef_0_0 0 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 9: Extracting a member of element inserted via Insert
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_struct_v2int_int_int Function\n" +
- "%2 = OpLoad %struct_v2int_int_int %n\n" +
- "%3 = OpCompositeInsert %struct_v2int_int_int %102 %2 0\n" +
- "%4 = OpCompositeExtract %int %3 0 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, 103),
- // Test case 10: Extracting a element that is partially changed by Insert. (Don't fold)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_struct_v2int_int_int Function\n" +
- "%2 = OpLoad %struct_v2int_int_int %n\n" +
- "%3 = OpCompositeInsert %struct_v2int_int_int %int_0 %2 0 1\n" +
- "%4 = OpCompositeExtract %v2int %3 0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, 0),
- // Test case 11: Extracting from result of vector shuffle (first input)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%2 = OpLoad %v2int %n\n" +
- "%3 = OpVectorShuffle %v2int %102 %2 3 0\n" +
- "%4 = OpCompositeExtract %int %3 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, INT_7_ID),
- // Test case 12: Extracting from result of vector shuffle (second input)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%2 = OpLoad %v2int %n\n" +
- "%3 = OpVectorShuffle %v2int %2 %102 2 0\n" +
- "%4 = OpCompositeExtract %int %3 0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, INT_7_ID),
- // Test case 13: https://github.com/KhronosGroup/SPIRV-Tools/issues/2608
- // Out of bounds access. Do not fold.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1\n" +
- "%3 = OpCompositeExtract %float %2 4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0),
- // Test case 14: https://github.com/KhronosGroup/SPIRV-Tools/issues/3631
- // Extract the component right after the vector constituent.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeConstruct %v2int %int_0 %int_0\n" +
- "%3 = OpCompositeConstruct %v4int %2 %100 %int_0\n" +
- "%4 = OpCompositeExtract %int %3 2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, INT_0_ID),
- // Test case 15:
- // Don't fold extract fed by construct with vector result if the index is
- // past the last element.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeConstruct %v2int %int_0 %int_0\n" +
- "%3 = OpCompositeConstruct %v4int %2 %100 %int_0\n" +
- "%4 = OpCompositeExtract %int %3 4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, 0)
- ));
- INSTANTIATE_TEST_SUITE_P(CompositeConstructFoldingTest, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold Extracts feeding construct
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCopyObject %v4int %v4int_0_0_0_0\n" +
- "%3 = OpCompositeExtract %int %2 0\n" +
- "%4 = OpCompositeExtract %int %2 1\n" +
- "%5 = OpCompositeExtract %int %2 2\n" +
- "%6 = OpCompositeExtract %int %2 3\n" +
- "%7 = OpCompositeConstruct %v4int %3 %4 %5 %6\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 7, 2),
- // Test case 1: Don't fold Extracts feeding construct (Different source)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCopyObject %v4int %v4int_0_0_0_0\n" +
- "%3 = OpCompositeExtract %int %2 0\n" +
- "%4 = OpCompositeExtract %int %2 1\n" +
- "%5 = OpCompositeExtract %int %2 2\n" +
- "%6 = OpCompositeExtract %int %v4int_0_0_0_0 3\n" +
- "%7 = OpCompositeConstruct %v4int %3 %4 %5 %6\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 7, 0),
- // Test case 2: Don't fold Extracts feeding construct (bad indices)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCopyObject %v4int %v4int_0_0_0_0\n" +
- "%3 = OpCompositeExtract %int %2 0\n" +
- "%4 = OpCompositeExtract %int %2 0\n" +
- "%5 = OpCompositeExtract %int %2 2\n" +
- "%6 = OpCompositeExtract %int %2 3\n" +
- "%7 = OpCompositeConstruct %v4int %3 %4 %5 %6\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 7, 0),
- // Test case 3: Don't fold Extracts feeding construct (different type)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCopyObject %struct_v2int_int_int %struct_v2int_int_int_null\n" +
- "%3 = OpCompositeExtract %v2int %2 0\n" +
- "%4 = OpCompositeExtract %int %2 1\n" +
- "%5 = OpCompositeExtract %int %2 2\n" +
- "%7 = OpCompositeConstruct %v4int %3 %4 %5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 7, 0),
- // Test case 4: Fold construct with constants to constant.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeConstruct %v2int %103 %103\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, VEC2_0_ID),
- // Test case 5: Don't segfault when trying to fold an OpCompositeConstruct
- // for an empty struct, and we reached the id limit.
- InstructionFoldingCase<uint32_t>(
- Header() + "%empty_struct = OpTypeStruct\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%4194303 = OpCompositeConstruct %empty_struct\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4194303, 0)
- ));
- INSTANTIATE_TEST_SUITE_P(PhiFoldingTest, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Fold phi with the same values for all edges.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- " OpBranchConditional %true %l1 %l2\n" +
- "%l1 = OpLabel\n" +
- " OpBranch %merge_lab\n" +
- "%l2 = OpLabel\n" +
- " OpBranch %merge_lab\n" +
- "%merge_lab = OpLabel\n" +
- "%2 = OpPhi %int %100 %l1 %100 %l2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, INT_0_ID),
- // Test case 1: Fold phi in pass through loop.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- " OpBranch %l1\n" +
- "%l1 = OpLabel\n" +
- "%2 = OpPhi %int %100 %main_lab %2 %l1\n" +
- " OpBranchConditional %true %l1 %merge_lab\n" +
- "%merge_lab = OpLabel\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, INT_0_ID),
- // Test case 2: Don't Fold phi because of different values.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- " OpBranch %l1\n" +
- "%l1 = OpLabel\n" +
- "%2 = OpPhi %int %int_0 %main_lab %int_3 %l1\n" +
- " OpBranchConditional %true %l1 %merge_lab\n" +
- "%merge_lab = OpLabel\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0)
- ));
- INSTANTIATE_TEST_SUITE_P(FloatRedundantFoldingTest, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Don't fold n + 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFAdd %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 1: Don't fold n - 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFSub %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 2: Don't fold n * 2.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFMul %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 3: Fold n + 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFAdd %float %3 %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 4: Fold 0.0 + n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFAdd %float %float_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 5: Fold n - 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFSub %float %3 %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 6: Fold n * 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFMul %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 7: Fold 1.0 * n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFMul %float %float_1 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 8: Fold n / 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFDiv %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 9: Fold n % 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFMod %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, FLOAT_0_ID),
- // Test case 10: Fold n * 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFMul %float %3 %104\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, FLOAT_0_ID),
- // Test case 11: Fold 0.0 * n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFMul %float %104 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, FLOAT_0_ID),
- // Test case 12: Fold 0.0 / n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFDiv %float %104 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, FLOAT_0_ID),
- // Test case 13: Fold 0.0 % n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFMod %float %104 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, FLOAT_0_ID),
- // Test case 14: Don't fold mix(a, b, 2.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%a = OpVariable %_ptr_float Function\n" +
- "%b = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %a\n" +
- "%4 = OpLoad %float %b\n" +
- "%2 = OpExtInst %float %1 FMix %3 %4 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 15: Fold mix(a, b, 0.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%a = OpVariable %_ptr_float Function\n" +
- "%b = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %a\n" +
- "%4 = OpLoad %float %b\n" +
- "%2 = OpExtInst %float %1 FMix %3 %4 %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 16: Fold mix(a, b, 1.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%a = OpVariable %_ptr_float Function\n" +
- "%b = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %a\n" +
- "%4 = OpLoad %float %b\n" +
- "%2 = OpExtInst %float %1 FMix %3 %4 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4),
- // Test case 17: Fold vector fadd with null
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%a = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %a\n" +
- "%3 = OpFAdd %v2float %2 %v2float_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 2),
- // Test case 18: Fold vector fadd with null
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%a = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %a\n" +
- "%3 = OpFAdd %v2float %v2float_null %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 2),
- // Test case 19: Fold vector fsub with null
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%a = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %a\n" +
- "%3 = OpFSub %v2float %2 %v2float_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 2),
- // Test case 20: Fold 0.0(half) * n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_half Function\n" +
- "%3 = OpLoad %half %n\n" +
- "%2 = OpFMul %half %108 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, HALF_0_ID),
- // Test case 21: Don't fold 1.0(half) * n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_half Function\n" +
- "%3 = OpLoad %half %n\n" +
- "%2 = OpFMul %half %half_1 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 22: Don't fold 1.0 * 1.0 (half)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFMul %half %half_1 %half_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 23: Don't fold (0.0, 1.0) * (0.0, 1.0) (half)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFMul %v2half %half_0_1 %half_0_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 24: Don't fold (0.0, 1.0) dotp (0.0, 1.0) (half)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpDot %half %half_0_1 %half_0_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 25: Don't fold 1.0(half) / 2.0(half)
- // We do not have to code to emulate 16-bit float operations. Just make sure we do not crash.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_half Function\n" +
- "%3 = OpLoad %half %n\n" +
- "%2 = OpFDiv %half %half_1 %half_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 26: Don't fold OpFNegate for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFNegate %float_coop_matrix %undef_float_coop_matrix\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 27: Don't fold OpIAdd for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFAdd %float_coop_matrix %undef_float_coop_matrix %undef_float_coop_matrix\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 28: Don't fold OpISub for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFSub %float_coop_matrix %undef_float_coop_matrix %undef_float_coop_matrix\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 29: Don't fold OpIMul for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFMul %float_coop_matrix %undef_float_coop_matrix %undef_float_coop_matrix\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 30: Don't fold OpSDiv for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %float_coop_matrix %undef_float_coop_matrix %undef_float_coop_matrix\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 31: Don't fold OpMatrixTimesScalar for cooperative matrices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpMatrixTimesScalar %float_coop_matrix %undef_float_coop_matrix %float_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0)
- ));
- INSTANTIATE_TEST_SUITE_P(DoubleRedundantFoldingTest, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Don't fold n + 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFAdd %double %3 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 1: Don't fold n - 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFSub %double %3 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 2: Don't fold n * 2.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFMul %double %3 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 3: Fold n + 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFAdd %double %3 %double_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 4: Fold 0.0 + n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFAdd %double %double_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 5: Fold n - 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFSub %double %3 %double_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 6: Fold n * 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFMul %double %3 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 7: Fold 1.0 * n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFMul %double %double_1 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 8: Fold n / 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFDiv %double %3 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 9: Fold n * 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFMul %double %3 %105\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, DOUBLE_0_ID),
- // Test case 10: Fold 0.0 * n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFMul %double %105 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, DOUBLE_0_ID),
- // Test case 11: Fold 0.0 / n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFDiv %double %105 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, DOUBLE_0_ID),
- // Test case 12: Don't fold mix(a, b, 2.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%a = OpVariable %_ptr_double Function\n" +
- "%b = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %a\n" +
- "%4 = OpLoad %double %b\n" +
- "%2 = OpExtInst %double %1 FMix %3 %4 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 13: Fold mix(a, b, 0.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%a = OpVariable %_ptr_double Function\n" +
- "%b = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %a\n" +
- "%4 = OpLoad %double %b\n" +
- "%2 = OpExtInst %double %1 FMix %3 %4 %double_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 14: Fold mix(a, b, 1.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%a = OpVariable %_ptr_double Function\n" +
- "%b = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %a\n" +
- "%4 = OpLoad %double %b\n" +
- "%2 = OpExtInst %double %1 FMix %3 %4 %double_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4)
- ));
- INSTANTIATE_TEST_SUITE_P(FloatVectorRedundantFoldingTest, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Don't fold a * vec4(0.0, 0.0, 0.0, 1.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4float Function\n" +
- "%3 = OpLoad %v4float %n\n" +
- "%2 = OpFMul %v4float %3 %v4float_0_0_0_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 1: Fold a * vec4(0.0, 0.0, 0.0, 0.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4float Function\n" +
- "%3 = OpLoad %v4float %n\n" +
- "%2 = OpFMul %v4float %3 %106\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, VEC4_0_ID),
- // Test case 2: Fold a * vec4(1.0, 1.0, 1.0, 1.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4float Function\n" +
- "%3 = OpLoad %v4float %n\n" +
- "%2 = OpFMul %v4float %3 %v4float_1_1_1_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3)
- ));
- INSTANTIATE_TEST_SUITE_P(DoubleVectorRedundantFoldingTest, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Don't fold a * vec4(0.0, 0.0, 0.0, 1.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpLoad %v4double %n\n" +
- "%2 = OpFMul %v4double %3 %v4double_0_0_0_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 1: Fold a * vec4(0.0, 0.0, 0.0, 0.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpLoad %v4double %n\n" +
- "%2 = OpFMul %v4double %3 %106\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, DVEC4_0_ID),
- // Test case 2: Fold a + vec4(0.0, 0.0, 0.0, 0.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpLoad %v4double %n\n" +
- "%2 = OpFAdd %v4double %3 %106\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 3: Fold a - vec4(0.0, 0.0, 0.0, 0.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpLoad %v4double %n\n" +
- "%2 = OpFSub %v4double %3 %106\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 4: Fold a * vec4(1.0, 1.0, 1.0, 1.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpLoad %v4double %n\n" +
- "%2 = OpFMul %v4double %3 %v4double_1_1_1_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3)
- ));
- INSTANTIATE_TEST_SUITE_P(IntegerRedundantFoldingTest, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Don't fold n + 1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpIAdd %uint %3 %uint_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 1: Don't fold 1 + n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpIAdd %uint %uint_1 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 2: Fold n | 0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpBitwiseOr %uint %3 %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 3: Fold n ^ 0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpBitwiseXor %uint %3 %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 4: Fold n >> 0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpShiftRightLogical %uint %3 %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 5: Fold n >> 0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpShiftRightArithmetic %uint %3 %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 6: Fold n << 0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpShiftLeftLogical %uint %3 %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 7: Fold n + 0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpIAdd %uint %3 %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 8: Fold n - 0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpISub %uint %3 %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 9: Fold 0 | n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpBitwiseOr %uint %uint_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 10: Fold 0 ^ n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpBitwiseXor %uint %uint_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 11: Fold 0 + n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpIAdd %uint %uint_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 12: Don't fold n + (1,0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%3 = OpLoad %v2int %n\n" +
- "%2 = OpIAdd %v2int %3 %v2int_1_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 13: Don't fold (1,0) + n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%3 = OpLoad %v2int %n\n" +
- "%2 = OpIAdd %v2int %v2int_1_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 14: Fold n + (0,0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%3 = OpLoad %v2int %n\n" +
- "%2 = OpIAdd %v2int %3 %v2int_0_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 15: Fold (0,0) + n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%3 = OpLoad %v2int %n\n" +
- "%2 = OpIAdd %v2int %v2int_0_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 16: Fold n | (0,0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%3 = OpLoad %v2int %n\n" +
- "%2 = OpBitwiseOr %v2int %3 %v2int_0_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 17: Fold (0,0) | n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%3 = OpLoad %v2int %n\n" +
- "%2 = OpBitwiseOr %v2int %v2int_0_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 18: Fold 0 >> n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpShiftRightLogical %uint %109 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, UINT_0_ID),
- // Test case 19: Fold 0 >> n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpShiftRightArithmetic %uint %109 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, UINT_0_ID),
- // Test case 20: Fold 0 << n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpShiftLeftLogical %uint %109 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, UINT_0_ID),
- // Test case 21: Fold 0 / n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %int %n\n" +
- "%2 = OpSDiv %int %100 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, INT_0_ID),
- // Test case 22: Fold 0 / n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpUDiv %uint %109 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, UINT_0_ID),
- // Test case 23: Fold 0 % n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpSMod %int %int_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, INT_0_ID),
- // Test case 24: Fold 0 % n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpUMod %uint %109 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, UINT_0_ID),
- // Test case 25: Fold n % 1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %int %n\n" +
- "%2 = OpSMod %int %3 %int_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, INT_NULL_ID),
- // Test case 26: Fold n % 1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_uint Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpUMod %uint %3 %uint_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, UINT_NULL_ID),
- // Test case 27: Don't fold because of undefined value. Using 4294967295
- // means that entry is undefined. We do not expect it to ever happen, so
- // not worth folding.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpVectorShuffle %v2int %v2int_null %v2int_2_3 4294967295 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 28: Don't fold because of undefined value. Using 4294967295
- // means that entry is undefined. We do not expect it to ever happen, so
- // not worth folding.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpVectorShuffle %v2int %v2int_null %v2int_2_3 0 4294967295 \n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0)
- ));
- INSTANTIATE_TEST_SUITE_P(ClampAndCmpLHS, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Don't Fold 0.0 < clamp(-1, 1)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFUnordLessThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 1: Don't Fold 0.0 < clamp(-1, 1)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFOrdLessThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 2: Don't Fold 0.0 <= clamp(-1, 1)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFUnordLessThanEqual %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 3: Don't Fold 0.0 <= clamp(-1, 1)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFOrdLessThanEqual %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 4: Don't Fold 0.0 > clamp(-1, 1)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFUnordGreaterThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 5: Don't Fold 0.0 > clamp(-1, 1)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFOrdGreaterThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 6: Don't Fold 0.0 >= clamp(-1, 1)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFUnordGreaterThanEqual %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 7: Don't Fold 0.0 >= clamp(-1, 1)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFOrdGreaterThanEqual %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 8: Don't Fold 0.0 < clamp(0, 1)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_0 %float_1\n" +
- "%2 = OpFUnordLessThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 9: Don't Fold 0.0 < clamp(0, 1)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_0 %float_1\n" +
- "%2 = OpFOrdLessThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 10: Don't Fold 0.0 > clamp(-1, 0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_0\n" +
- "%2 = OpFUnordGreaterThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 11: Don't Fold 0.0 > clamp(-1, 0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_0\n" +
- "%2 = OpFOrdGreaterThan %bool %float_0 %clamp\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0)
- ));
- INSTANTIATE_TEST_SUITE_P(ClampAndCmpRHS, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Don't Fold clamp(-1, 1) < 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFUnordLessThan %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 1: Don't Fold clamp(-1, 1) < 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFOrdLessThan %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 2: Don't Fold clamp(-1, 1) <= 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFUnordLessThanEqual %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 3: Don't Fold clamp(-1, 1) <= 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFOrdLessThanEqual %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 4: Don't Fold clamp(-1, 1) > 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFUnordGreaterThan %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 5: Don't Fold clamp(-1, 1) > 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFOrdGreaterThan %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 6: Don't Fold clamp(-1, 1) >= 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFUnordGreaterThanEqual %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 7: Don't Fold clamp(-1, 1) >= 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_1\n" +
- "%2 = OpFOrdGreaterThanEqual %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 8: Don't Fold clamp(-1, 0) < 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_0\n" +
- "%2 = OpFUnordLessThan %bool %clamp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 9: Don't Fold clamp(0, 1) < 1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_0 %float_1\n" +
- "%2 = OpFOrdLessThan %bool %clamp %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 10: Don't Fold clamp(-1, 0) > -1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_0\n" +
- "%2 = OpFUnordGreaterThan %bool %clamp %float_n1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 11: Don't Fold clamp(-1, 0) > -1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%ld = OpLoad %float %n\n" +
- "%clamp = OpExtInst %float %1 FClamp %ld %float_n1 %float_0\n" +
- "%2 = OpFOrdGreaterThan %bool %clamp %float_n1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0)
- ));
- INSTANTIATE_TEST_SUITE_P(FToIConstantFoldingTest, IntegerInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Fold int(3.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpConvertFToS %int %float_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 1: Fold uint(3.0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpConvertFToU %int %float_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3)
- ));
- INSTANTIATE_TEST_SUITE_P(IToFConstantFoldingTest, FloatInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Fold float(3)
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpConvertSToF %float %int_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3.0),
- // Test case 1: Fold float(3u)
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpConvertUToF %float %uint_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3.0)
- ));
- // clang-format on
- using ToNegateFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<uint32_t>>;
- TEST_P(ToNegateFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) =
- FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- EXPECT_TRUE((inst == nullptr) == (tc.expected_result == 0));
- if (inst != nullptr) {
- EXPECT_EQ(inst->opcode(), spv::Op::OpFNegate);
- EXPECT_EQ(inst->GetSingleWordInOperand(0), tc.expected_result);
- }
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(FloatRedundantSubFoldingTest, ToNegateFoldingTest,
- ::testing::Values(
- // Test case 0: Don't fold 1.0 - n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFSub %float %float_1 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 1: Fold 0.0 - n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFSub %float %float_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 2: Don't fold (0,0,0,1) - n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4float Function\n" +
- "%3 = OpLoad %v4float %n\n" +
- "%2 = OpFSub %v4float %v4float_0_0_0_1 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 3: Fold (0,0,0,0) - n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4float Function\n" +
- "%3 = OpLoad %v4float %n\n" +
- "%2 = OpFSub %v4float %v4float_0_0_0_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3)
- ));
- INSTANTIATE_TEST_SUITE_P(DoubleRedundantSubFoldingTest, ToNegateFoldingTest,
- ::testing::Values(
- // Test case 0: Don't fold 1.0 - n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFSub %double %double_1 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 1: Fold 0.0 - n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%3 = OpLoad %double %n\n" +
- "%2 = OpFSub %double %double_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 2: Don't fold (0,0,0,1) - n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpLoad %v4double %n\n" +
- "%2 = OpFSub %v4double %v4double_0_0_0_1 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 3: Fold (0,0,0,0) - n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpLoad %v4double %n\n" +
- "%2 = OpFSub %v4double %v4double_0_0_0_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3)
- ));
- using MatchingInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<bool>>;
- TEST_P(MatchingInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) = FoldInstruction(tc.test_body, tc.id_to_fold,SPV_ENV_UNIVERSAL_1_1);
- EXPECT_EQ(inst != nullptr, tc.expected_result);
- if (inst != nullptr) {
- Match(tc.test_body, context.get());
- }
- }
- INSTANTIATE_TEST_SUITE_P(RedundantIntegerMatching, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Fold 0 + n (change sign)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[uint:%\\w+]] = OpTypeInt 32 0\n" +
- "; CHECK: %2 = OpBitcast [[uint]] %3\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%3 = OpLoad %uint %n\n" +
- "%2 = OpIAdd %uint %int_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 2, true),
- // Test case 0: Fold 0 + n (change sign)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: %2 = OpBitcast [[int]] %3\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%3 = OpLoad %int %n\n" +
- "%2 = OpIAdd %int %uint_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 2, true)
- ));
- INSTANTIATE_TEST_SUITE_P(MergeNegateTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold consecutive fnegate
- // -(-x) = x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float:%\\w+]]\n" +
- "; CHECK: %4 = OpCopyObject [[float]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFNegate %float %2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 1: fold fnegate(fmul with const).
- // -(x * 2.0) = x * -2.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[ld]] [[float_n2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFMul %float %2 %float_2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 2: fold fnegate(fmul with const).
- // -(2.0 * x) = x * 2.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[ld]] [[float_n2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFMul %float %float_2 %2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 3: fold fnegate(fdiv with const).
- // -(x / 2.0) = x * -0.5
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n0p5:%\\w+]] = OpConstant [[float]] -0.5\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[ld]] [[float_n0p5]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %2 %float_2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 4: fold fnegate(fdiv with const).
- // -(2.0 / x) = -2.0 / x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFDiv [[float]] [[float_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %float_2 %2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 5: fold fnegate(fadd with const).
- // -(2.0 + x) = -2.0 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %float_2 %2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 6: fold fnegate(fadd with const).
- // -(x + 2.0) = -2.0 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %2 %float_2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 7: fold fnegate(fsub with const).
- // -(2.0 - x) = x - 2.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[ld]] [[float_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %float_2 %2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 8: fold fnegate(fsub with const).
- // -(x - 2.0) = 2.0 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %2 %float_2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 9: fold consecutive snegate
- // -(-x) = x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int:%\\w+]]\n" +
- "; CHECK: %4 = OpCopyObject [[int]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSNegate %int %2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 10: fold consecutive vector negate
- // -(-x) = x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2float:%\\w+]]\n" +
- "; CHECK: %4 = OpCopyObject [[v2float]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %var\n" +
- "%3 = OpFNegate %v2float %2\n" +
- "%4 = OpFNegate %v2float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 11: fold snegate(iadd with const).
- // -(2 + x) = -2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: OpConstant [[int]] -2147483648\n" +
- "; CHECK: [[int_n2:%\\w+]] = OpConstant [[int]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpISub [[int]] [[int_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIAdd %int %int_2 %2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 12: fold snegate(iadd with const).
- // -(x + 2) = -2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: OpConstant [[int]] -2147483648\n" +
- "; CHECK: [[int_n2:%\\w+]] = OpConstant [[int]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpISub [[int]] [[int_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIAdd %int %2 %int_2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 13: fold snegate(isub with const).
- // -(2 - x) = x - 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpISub [[int]] [[ld]] [[int_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpISub %int %int_2 %2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 14: fold snegate(isub with const).
- // -(x - 2) = 2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpISub [[int]] [[int_2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpISub %int %2 %int_2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 15: fold snegate(iadd with const).
- // -(x + 2) = -2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_n2:%\\w+]] = OpConstant [[long]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpISub [[long]] [[long_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpIAdd %long %2 %long_2\n" +
- "%4 = OpSNegate %long %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 16: fold snegate(isub with const).
- // -(2 - x) = x - 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_2:%\\w+]] = OpConstant [[long]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpISub [[long]] [[ld]] [[long_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpISub %long %long_2 %2\n" +
- "%4 = OpSNegate %long %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 17: fold snegate(isub with const).
- // -(x - 2) = 2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_2:%\\w+]] = OpConstant [[long]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpISub [[long]] [[long_2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpISub %long %2 %long_2\n" +
- "%4 = OpSNegate %long %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 18: fold -vec4(-1.0, 2.0, 1.0, 3.0)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[v4float:%\\w+]] = OpTypeVector [[float]] 4{{[[:space:]]}}\n" +
- "; CHECK: [[float_n1:%\\w+]] = OpConstant [[float]] -1{{[[:space:]]}}\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1{{[[:space:]]}}\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[float_n3:%\\w+]] = OpConstant [[float]] -3{{[[:space:]]}}\n" +
- "; CHECK: [[v4float_1_n2_n1_n3:%\\w+]] = OpConstantComposite [[v4float]] [[float_1]] [[float_n2]] [[float_n1]] [[float_n3]]\n" +
- "; CHECK: %2 = OpCopyObject [[v4float]] [[v4float_1_n2_n1_n3]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFNegate %v4float %v4float_n1_2_1_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 19: fold vector fnegate with null
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v2double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: [[double_n0:%\\w+]] = OpConstant [[double]] -0\n" +
- "; CHECK: [[v2double_0_0:%\\w+]] = OpConstantComposite [[v2double]] [[double_n0]] [[double_n0]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2double]] [[v2double_0_0]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFNegate %v2double %v2double_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 20: fold snegate with OpIMul.
- // -(x * 2) = x * -2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_n2:%\\w+]] = OpConstant [[long]] -2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpIMul [[long]] [[ld]] [[long_n2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpIMul %long %2 %long_2\n" +
- "%4 = OpSNegate %long %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 21: fold snegate with OpIMul.
- // -(x * 2) = x * -2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK-DAG: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK-DAG: [[uint:%\\w+]] = OpTypeInt 32 0\n" +
- "; CHECK: [[uint_n2:%\\w+]] = OpConstant [[uint]] 4294967294\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpIMul [[int]] [[ld]] [[uint_n2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIMul %int %2 %uint_2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 22: fold snegate with OpIMul.
- // -(-24 * x) = x * 24
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK-DAG: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int_24:%\\w+]] = OpConstant [[int]] 24\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpIMul [[int]] [[ld]] [[int_24]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIMul %int %int_n24 %2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 23: fold snegate with OpIMul with UINT_MAX
- // -(UINT_MAX * x) = x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpCopyObject [[int]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIMul %int %uint_max %2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 24: fold snegate with OpIMul using -INT_MAX
- // -(x * 2147483649u) = x * 2147483647u
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[uint:%\\w+]] = OpTypeInt 32 0\n" +
- "; CHECK: [[uint_2147483647:%\\w+]] = OpConstant [[uint]] 2147483647\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpIMul [[int]] [[ld]] [[uint_2147483647]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIMul %int %2 %uint_2147483649\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 25: fold snegate with OpSDiv (long).
- // -(x / 2) = x / -2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_n2:%\\w+]] = OpConstant [[long]] -2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpSDiv [[long]] [[ld]] [[long_n2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpSDiv %long %2 %long_2\n" +
- "%4 = OpSNegate %long %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 26: fold snegate with OpSDiv (int).
- // -(x / 2) = x / -2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK-DAG: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK-DAG: [[uint:%\\w+]] = OpTypeInt 32 0\n" +
- "; CHECK: [[uint_n2:%\\w+]] = OpConstant [[uint]] 4294967294\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpSDiv [[int]] [[ld]] [[uint_n2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSDiv %int %2 %uint_2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 27: fold snegate with OpSDiv.
- // -(-24 / x) = 24 / x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK-DAG: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int_24:%\\w+]] = OpConstant [[int]] 24\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpSDiv [[int]] [[int_24]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSDiv %int %int_n24 %2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 28: fold snegate with OpSDiv with UINT_MAX
- // -(UINT_MAX / x) = (1 / x)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[uint:%\\w+]] = OpTypeInt 32 0\n" +
- "; CHECK: [[uint_1:%\\w+]] = OpConstant [[uint]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpSDiv [[int]] [[uint_1]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSDiv %int %uint_max %2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 29: fold snegate with OpSDiv using -INT_MAX
- // -(x / 2147483647u) = x / 2147483647
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[uint:%\\w+]] = OpTypeInt 32 0\n" +
- "; CHECK: [[uint_2147483647:%\\w+]] = OpConstant [[uint]] 2147483647\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpSDiv [[int]] [[ld]] [[uint_2147483647]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSDiv %int %2 %uint_2147483649\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 30: Don't fold snegate int OpUDiv. The operands are interpreted
- // as unsigned, so negating an operand is not the same a negating the
- // result.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpUDiv %int %2 %uint_1\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, false)
- ));
- INSTANTIATE_TEST_SUITE_P(ReciprocalFDivTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: scalar reicprocal
- // x / 0.5 = x * 2.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %3 = OpFMul [[float]] [[ld]] [[float_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %2 %float_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 3, true),
- // Test case 1: Unfoldable
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_0:%\\w+]] = OpConstant [[float]] 0\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %3 = OpFDiv [[float]] [[ld]] [[float_0]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %2 %104\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 3, false),
- // Test case 2: Vector reciprocal
- // x / {2.0, 0.5} = x * {0.5, 2.0}
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[v2float:%\\w+]] = OpTypeVector [[float]] 2\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[float_0p5:%\\w+]] = OpConstant [[float]] 0.5\n" +
- "; CHECK: [[v2float_0p5_2:%\\w+]] = OpConstantComposite [[v2float]] [[float_0p5]] [[float_2]]\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2float]]\n" +
- "; CHECK: %3 = OpFMul [[v2float]] [[ld]] [[v2float_0p5_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %var\n" +
- "%3 = OpFDiv %v2float %2 %v2float_2_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 3, true),
- // Test case 3: double reciprocal
- // x / 2.0 = x * 0.5
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[double_0p5:%\\w+]] = OpConstant [[double]] 0.5\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[double]]\n" +
- "; CHECK: %3 = OpFMul [[double]] [[ld]] [[double_0p5]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_double Function\n" +
- "%2 = OpLoad %double %var\n" +
- "%3 = OpFDiv %double %2 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 3, true),
- // Test case 4: don't fold x / 0.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %var\n" +
- "%3 = OpFDiv %v2float %2 %v2float_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 3, false)
- ));
- INSTANTIATE_TEST_SUITE_P(MergeMulTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold consecutive fmuls
- // (x * 3.0) * 2.0 = x * 6.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_6:%\\w+]] = OpConstant [[float]] 6\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[ld]] [[float_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFMul %float %2 %float_3\n" +
- "%4 = OpFMul %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 1: fold consecutive fmuls
- // 2.0 * (x * 3.0) = x * 6.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_6:%\\w+]] = OpConstant [[float]] 6\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[ld]] [[float_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFMul %float %2 %float_3\n" +
- "%4 = OpFMul %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 2: fold consecutive fmuls
- // (3.0 * x) * 2.0 = x * 6.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_6:%\\w+]] = OpConstant [[float]] 6\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[ld]] [[float_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFMul %float %float_3 %2\n" +
- "%4 = OpFMul %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 3: fold vector fmul
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[v2float:%\\w+]] = OpTypeVector [[float]] 2\n" +
- "; CHECK: [[float_6:%\\w+]] = OpConstant [[float]] 6\n" +
- "; CHECK: [[v2float_6_6:%\\w+]] = OpConstantComposite [[v2float]] [[float_6]] [[float_6]]\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2float]]\n" +
- "; CHECK: %4 = OpFMul [[v2float]] [[ld]] [[v2float_6_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %var\n" +
- "%3 = OpFMul %v2float %2 %v2float_2_3\n" +
- "%4 = OpFMul %v2float %3 %v2float_3_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 4: fold double fmuls
- // (x * 3.0) * 2.0 = x * 6.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[double_6:%\\w+]] = OpConstant [[double]] 6\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[double]]\n" +
- "; CHECK: %4 = OpFMul [[double]] [[ld]] [[double_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_double Function\n" +
- "%2 = OpLoad %double %var\n" +
- "%3 = OpFMul %double %2 %double_3\n" +
- "%4 = OpFMul %double %3 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 5: fold 32 bit imuls
- // (x * 3) * 2 = x * 6
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int_6:%\\w+]] = OpConstant [[int]] 6\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpIMul [[int]] [[ld]] [[int_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIMul %int %2 %int_3\n" +
- "%4 = OpIMul %int %3 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 6: fold 64 bit imuls
- // (x * 3) * 2 = x * 6
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64\n" +
- "; CHECK: [[long_6:%\\w+]] = OpConstant [[long]] 6\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpIMul [[long]] [[ld]] [[long_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpIMul %long %2 %long_3\n" +
- "%4 = OpIMul %long %3 %long_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 7: merge vector integer mults
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[v2int:%\\w+]] = OpTypeVector [[int]] 2\n" +
- "; CHECK: [[int_6:%\\w+]] = OpConstant [[int]] 6\n" +
- "; CHECK: [[v2int_6_6:%\\w+]] = OpConstantComposite [[v2int]] [[int_6]] [[int_6]]\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2int]]\n" +
- "; CHECK: %4 = OpIMul [[v2int]] [[ld]] [[v2int_6_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2int Function\n" +
- "%2 = OpLoad %v2int %var\n" +
- "%3 = OpIMul %v2int %2 %v2int_2_3\n" +
- "%4 = OpIMul %v2int %3 %v2int_3_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 8: merge fmul of fdiv
- // 2.0 * (2.0 / x) = 4.0 / x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_4:%\\w+]] = OpConstant [[float]] 4\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFDiv [[float]] [[float_4]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %float_2 %2\n" +
- "%4 = OpFMul %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 9: merge fmul of fdiv
- // (2.0 / x) * 2.0 = 4.0 / x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_4:%\\w+]] = OpConstant [[float]] 4\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFDiv [[float]] [[float_4]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %float_2 %2\n" +
- "%4 = OpFMul %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 10: Do not merge imul of sdiv
- // 4 * (x / 2)
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSDiv %int %2 %int_2\n" +
- "%4 = OpIMul %int %int_4 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 11: Do not merge imul of sdiv
- // (x / 2) * 4
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSDiv %int %2 %int_2\n" +
- "%4 = OpIMul %int %3 %int_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 12: Do not merge imul of udiv
- // 4 * (x / 2)
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_uint Function\n" +
- "%2 = OpLoad %uint %var\n" +
- "%3 = OpUDiv %uint %2 %uint_2\n" +
- "%4 = OpIMul %uint %uint_4 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 13: Do not merge imul of udiv
- // (x / 2) * 4
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_uint Function\n" +
- "%2 = OpLoad %uint %var\n" +
- "%3 = OpUDiv %uint %2 %uint_2\n" +
- "%4 = OpIMul %uint %3 %uint_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 14: Don't fold
- // (x / 3) * 4
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_uint Function\n" +
- "%2 = OpLoad %uint %var\n" +
- "%3 = OpUDiv %uint %2 %uint_3\n" +
- "%4 = OpIMul %uint %3 %uint_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 15: merge vector fmul of fdiv
- // (x / {2,2}) * {4,4} = x * {2,2}
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[v2float:%\\w+]] = OpTypeVector [[float]] 2\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[v2float_2_2:%\\w+]] = OpConstantComposite [[v2float]] [[float_2]] [[float_2]]\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2float]]\n" +
- "; CHECK: %4 = OpFMul [[v2float]] [[ld]] [[v2float_2_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %var\n" +
- "%3 = OpFDiv %v2float %2 %v2float_2_2\n" +
- "%4 = OpFMul %v2float %3 %v2float_4_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 16: merge vector imul of snegate
- // (-x) * {2,2} = x * {-2,-2}
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[v2int:%\\w+]] = OpTypeVector [[int]] 2{{[[:space:]]}}\n" +
- "; CHECK: OpConstant [[int]] -2147483648{{[[:space:]]}}\n" +
- "; CHECK: [[int_n2:%\\w+]] = OpConstant [[int]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[v2int_n2_n2:%\\w+]] = OpConstantComposite [[v2int]] [[int_n2]] [[int_n2]]\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2int]]\n" +
- "; CHECK: %4 = OpIMul [[v2int]] [[ld]] [[v2int_n2_n2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2int Function\n" +
- "%2 = OpLoad %v2int %var\n" +
- "%3 = OpSNegate %v2int %2\n" +
- "%4 = OpIMul %v2int %3 %v2int_2_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 17: merge vector imul of snegate
- // {2,2} * (-x) = x * {-2,-2}
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[v2int:%\\w+]] = OpTypeVector [[int]] 2{{[[:space:]]}}\n" +
- "; CHECK: OpConstant [[int]] -2147483648{{[[:space:]]}}\n" +
- "; CHECK: [[int_n2:%\\w+]] = OpConstant [[int]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[v2int_n2_n2:%\\w+]] = OpConstantComposite [[v2int]] [[int_n2]] [[int_n2]]\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2int]]\n" +
- "; CHECK: %4 = OpIMul [[v2int]] [[ld]] [[v2int_n2_n2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2int Function\n" +
- "%2 = OpLoad %v2int %var\n" +
- "%3 = OpSNegate %v2int %2\n" +
- "%4 = OpIMul %v2int %v2int_2_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 18: Fold OpVectorTimesScalar
- // {4,4} = OpVectorTimesScalar v2float {2,2} 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[v2float:%\\w+]] = OpTypeVector [[float]] 2\n" +
- "; CHECK: [[float_4:%\\w+]] = OpConstant [[float]] 4\n" +
- "; CHECK: [[v2float_4_4:%\\w+]] = OpConstantComposite [[v2float]] [[float_4]] [[float_4]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2float]] [[v2float_4_4]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesScalar %v2float %v2float_2_2 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 19: Fold OpVectorTimesScalar
- // {0,0} = OpVectorTimesScalar v2float v2float_null -1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[v2float:%\\w+]] = OpTypeVector [[float]] 2\n" +
- "; CHECK: [[v2float_null:%\\w+]] = OpConstantNull [[v2float]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2float]] [[v2float_null]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesScalar %v2float %v2float_null %float_n1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 20: Fold OpVectorTimesScalar
- // {4,4} = OpVectorTimesScalar v2double {2,2} 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v2double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: [[double_4:%\\w+]] = OpConstant [[double]] 4\n" +
- "; CHECK: [[v2double_4_4:%\\w+]] = OpConstantComposite [[v2double]] [[double_4]] [[double_4]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2double]] [[v2double_4_4]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesScalar %v2double %v2double_2_2 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 21: Fold OpVectorTimesScalar
- // {0,0} = OpVectorTimesScalar v2double {0,0} n
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v2double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: {{%\\w+}} = OpConstant [[double]] 0\n" +
- "; CHECK: [[double_0:%\\w+]] = OpConstant [[double]] 0\n" +
- "; CHECK: [[v2double_0_0:%\\w+]] = OpConstantComposite [[v2double]] [[double_0]] [[double_0]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2double]] [[v2double_0_0]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%load = OpLoad %double %n\n" +
- "%2 = OpVectorTimesScalar %v2double %v2double_0_0 %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 22: Fold OpVectorTimesScalar
- // {0,0} = OpVectorTimesScalar v2double n 0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v2double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: [[v2double_null:%\\w+]] = OpConstantNull [[v2double]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2double]] [[v2double_null]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2double Function\n" +
- "%load = OpLoad %v2double %n\n" +
- "%2 = OpVectorTimesScalar %v2double %load %double_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 23: merge fmul of fdiv
- // x * (y / x) = y
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[ldx:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: [[ldy:%\\w+]] = OpLoad [[float]] [[y:%\\w+]]\n" +
- "; CHECK: %5 = OpCopyObject [[float]] [[ldy]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %x\n" +
- "%3 = OpLoad %float %y\n" +
- "%4 = OpFDiv %float %3 %2\n" +
- "%5 = OpFMul %float %2 %4\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 5, true),
- // Test case 24: merge fmul of fdiv
- // (y / x) * x = y
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[ldx:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: [[ldy:%\\w+]] = OpLoad [[float]] [[y:%\\w+]]\n" +
- "; CHECK: %5 = OpCopyObject [[float]] [[ldy]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %x\n" +
- "%3 = OpLoad %float %y\n" +
- "%4 = OpFDiv %float %3 %2\n" +
- "%5 = OpFMul %float %4 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 5, true),
- // Test case 25: fold overflowing signed 32 bit imuls
- // (x * 1073741824) * 2 = x * int_min
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32\n" +
- "; CHECK: [[int_min:%\\w+]] = OpConstant [[int]] -2147483648\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpIMul [[int]] [[ld]] [[int_min]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIMul %int %2 %int_1073741824\n" +
- "%4 = OpIMul %int %3 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 26: fold overflowing signed 64 bit imuls
- // (x * 4611686018427387904) * 2 = x * long_min
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64\n" +
- "; CHECK: [[long_min:%\\w+]] = OpConstant [[long]] -9223372036854775808\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpIMul [[long]] [[ld]] [[long_min]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpIMul %long %2 %long_4611686018427387904\n" +
- "%4 = OpIMul %long %3 %long_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 27: fold overflowing 32 bit unsigned imuls
- // (x * 2147483649) * 2 = x * 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[uint:%\\w+]] = OpTypeInt 32 0\n" +
- "; CHECK: [[uint_2:%\\w+]] = OpConstant [[uint]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[uint]]\n" +
- "; CHECK: %4 = OpIMul [[uint]] [[ld]] [[uint_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_uint Function\n" +
- "%2 = OpLoad %uint %var\n" +
- "%3 = OpIMul %uint %2 %uint_2147483649\n" +
- "%4 = OpIMul %uint %3 %uint_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 28: fold overflowing 64 bit unsigned imuls
- // (x * 9223372036854775809) * 2 = x * 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[ulong:%\\w+]] = OpTypeInt 64 0\n" +
- "; CHECK: [[ulong_2:%\\w+]] = OpConstant [[ulong]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[ulong]]\n" +
- "; CHECK: %4 = OpIMul [[ulong]] [[ld]] [[ulong_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_ulong Function\n" +
- "%2 = OpLoad %ulong %var\n" +
- "%3 = OpIMul %ulong %2 %ulong_9223372036854775809\n" +
- "%4 = OpIMul %ulong %3 %ulong_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 29: fold underflowing signed 32 bit imuls
- // (x * (-858993459)) * 10 = x * 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32\n" +
- "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpIMul [[int]] [[ld]] [[int_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIMul %int %2 %int_n858993459\n" +
- "%4 = OpIMul %int %3 %int_10\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 30: fold underflowing signed 64 bit imuls
- // (x * (-3689348814741910323)) * 10 = x * 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64\n" +
- "; CHECK: [[long_2:%\\w+]] = OpConstant [[long]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpIMul [[long]] [[ld]] [[long_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpIMul %long %2 %long_n3689348814741910323\n" +
- "%4 = OpIMul %long %3 %long_10\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true)
- ));
- INSTANTIATE_TEST_SUITE_P(MergeDivTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: merge consecutive fdiv
- // 4.0 / (2.0 / x) = 2.0 * x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[float_2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %float_2 %2\n" +
- "%4 = OpFDiv %float %float_4 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 1: merge consecutive fdiv
- // 4.0 / (x / 2.0) = 8.0 / x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_8:%\\w+]] = OpConstant [[float]] 8\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFDiv [[float]] [[float_8]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %2 %float_2\n" +
- "%4 = OpFDiv %float %float_4 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 2: merge consecutive fdiv
- // (4.0 / x) / 2.0 = 2.0 / x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFDiv [[float]] [[float_2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %float_4 %2\n" +
- "%4 = OpFDiv %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 3: Do not merge consecutive sdiv
- // 4 / (2 / x)
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSDiv %int %int_2 %2\n" +
- "%4 = OpSDiv %int %int_4 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 4: Do not merge consecutive sdiv
- // 4 / (x / 2)
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSDiv %int %2 %int_2\n" +
- "%4 = OpSDiv %int %int_4 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 5: Do not merge consecutive sdiv
- // (4 / x) / 2
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSDiv %int %int_4 %2\n" +
- "%4 = OpSDiv %int %3 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 6: Do not merge consecutive sdiv
- // (x / 4) / 2
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSDiv %int %2 %int_4\n" +
- "%4 = OpSDiv %int %3 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 7: Do not merge sdiv of imul
- // 4 / (2 * x)
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIMul %int %int_2 %2\n" +
- "%4 = OpSDiv %int %int_4 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 8: Do not merge sdiv of imul
- // 4 / (x * 2)
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIMul %int %2 %int_2\n" +
- "%4 = OpSDiv %int %int_4 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 9: Do not merge sdiv of imul
- // (4 * x) / 2
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIMul %int %int_4 %2\n" +
- "%4 = OpSDiv %int %3 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 10: Do not merge sdiv of imul
- // (x * 4) / 2
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIMul %int %2 %int_4\n" +
- "%4 = OpSDiv %int %3 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 11: Do not merge sdiv of snegate. If %2 is INT_MIN, then the
- // sign of %3 will be the same as %2. This cannot be accounted for in OpSDiv.
- // Specifically, (-INT_MIN) / 2 != INT_MIN / -2.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSNegate %int %2\n" +
- "%4 = OpSDiv %int %3 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 12: Do not merge sdiv of snegate. If %2 is INT_MIN, then the
- // sign of %3 will be the same as %2. This cannot be accounted for in OpSDiv.
- // Specifically, 2 / (-INT_MIN) != -2 / INT_MIN.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSNegate %int %2\n" +
- "%4 = OpSDiv %int %int_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 13: Don't merge
- // (x / {null}) / {null}
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %2 %v2float_null\n" +
- "%4 = OpFDiv %float %3 %v2float_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 14: merge fmul of fdiv
- // (y * x) / x = y
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[ldx:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: [[ldy:%\\w+]] = OpLoad [[float]] [[y:%\\w+]]\n" +
- "; CHECK: %5 = OpCopyObject [[float]] [[ldy]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %x\n" +
- "%3 = OpLoad %float %y\n" +
- "%4 = OpFMul %float %3 %2\n" +
- "%5 = OpFDiv %float %4 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 5, true),
- // Test case 15: merge fmul of fdiv
- // (x * y) / x = y
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[ldx:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: [[ldy:%\\w+]] = OpLoad [[float]] [[y:%\\w+]]\n" +
- "; CHECK: %5 = OpCopyObject [[float]] [[ldy]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %x\n" +
- "%3 = OpLoad %float %y\n" +
- "%4 = OpFMul %float %2 %3\n" +
- "%5 = OpFDiv %float %4 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 5, true),
- // Test case 16: Do not merge udiv of snegate
- // (-x) / 2u
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_uint Function\n" +
- "%2 = OpLoad %uint %var\n" +
- "%3 = OpSNegate %uint %2\n" +
- "%4 = OpUDiv %uint %3 %uint_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 17: Do not merge udiv of snegate
- // 2u / (-x)
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_uint Function\n" +
- "%2 = OpLoad %uint %var\n" +
- "%3 = OpSNegate %uint %2\n" +
- "%4 = OpUDiv %uint %uint_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false)
- ));
- INSTANTIATE_TEST_SUITE_P(MergeAddTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: merge add of negate
- // (-x) + 2 = 2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFNegate %float %2\n" +
- "%4 = OpFAdd %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 1: merge add of negate
- // 2 + (-x) = 2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpSNegate %float %2\n" +
- "%4 = OpIAdd %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 2: merge add of negate
- // (-x) + 2 = 2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_2:%\\w+]] = OpConstant [[long]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpISub [[long]] [[long_2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpSNegate %long %2\n" +
- "%4 = OpIAdd %long %3 %long_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 3: merge add of negate
- // 2 + (-x) = 2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_2:%\\w+]] = OpConstant [[long]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpISub [[long]] [[long_2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpSNegate %long %2\n" +
- "%4 = OpIAdd %long %long_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 4: merge add of subtract
- // (x - 1) + 2 = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %2 %float_1\n" +
- "%4 = OpFAdd %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 5: merge add of subtract
- // (1 - x) + 2 = 3 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_3:%\\w+]] = OpConstant [[float]] 3\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_3]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %float_1 %2\n" +
- "%4 = OpFAdd %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 6: merge add of subtract
- // 2 + (x - 1) = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %2 %float_1\n" +
- "%4 = OpFAdd %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 7: merge add of subtract
- // 2 + (1 - x) = 3 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_3:%\\w+]] = OpConstant [[float]] 3\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_3]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %float_1 %2\n" +
- "%4 = OpFAdd %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 8: merge add of add
- // (x + 1) + 2 = x + 3
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_3:%\\w+]] = OpConstant [[float]] 3\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_3]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %2 %float_1\n" +
- "%4 = OpFAdd %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 9: merge add of add
- // (1 + x) + 2 = 3 + x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_3:%\\w+]] = OpConstant [[float]] 3\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_3]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %float_1 %2\n" +
- "%4 = OpFAdd %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 10: merge add of add
- // 2 + (x + 1) = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_3:%\\w+]] = OpConstant [[float]] 3\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_3]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %2 %float_1\n" +
- "%4 = OpFAdd %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 11: merge add of add
- // 2 + (1 + x) = 3 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_3:%\\w+]] = OpConstant [[float]] 3\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_3]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %float_1 %2\n" +
- "%4 = OpFAdd %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 12: fold overflowing signed 32 bit iadds
- // (x + int_max) + 1 = x + int_min
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32\n" +
- "; CHECK: [[int_min:%\\w+]] = OpConstant [[int]] -2147483648\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpIAdd [[int]] [[ld]] [[int_min]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIAdd %int %2 %int_max\n" +
- "%4 = OpIAdd %int %3 %int_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 13: fold overflowing signed 64 bit iadds
- // (x + long_max) + 1 = x + long_min
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64\n" +
- "; CHECK: [[long_min:%\\w+]] = OpConstant [[long]] -9223372036854775808\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpIAdd [[long]] [[ld]] [[long_min]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpIAdd %long %2 %long_max\n" +
- "%4 = OpIAdd %long %3 %long_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 14: fold overflowing 32 bit unsigned iadds
- // (x + uint_max) + 2 = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[uint:%\\w+]] = OpTypeInt 32 0\n" +
- "; CHECK: [[uint_1:%\\w+]] = OpConstant [[uint]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[uint]]\n" +
- "; CHECK: %4 = OpIAdd [[uint]] [[ld]] [[uint_1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_uint Function\n" +
- "%2 = OpLoad %uint %var\n" +
- "%3 = OpIAdd %uint %2 %uint_max\n" +
- "%4 = OpIAdd %uint %3 %uint_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 15: fold overflowing 64 bit unsigned iadds
- // (x + ulong_max) + 2 = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[ulong:%\\w+]] = OpTypeInt 64 0\n" +
- "; CHECK: [[ulong_1:%\\w+]] = OpConstant [[ulong]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[ulong]]\n" +
- "; CHECK: %4 = OpIAdd [[ulong]] [[ld]] [[ulong_1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_ulong Function\n" +
- "%2 = OpLoad %ulong %var\n" +
- "%3 = OpIAdd %ulong %2 %ulong_max\n" +
- "%4 = OpIAdd %ulong %3 %ulong_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 16: fold underflowing signed 32 bit iadds
- // (x + int_min) + (-1) = x + int_max
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32\n" +
- "; CHECK: [[int_max:%\\w+]] = OpConstant [[int]] 2147483647\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpIAdd [[int]] [[ld]] [[int_max]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIAdd %int %2 %int_min\n" +
- "%4 = OpIAdd %int %3 %int_n1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 17: fold underflowing signed 64 bit iadds
- // (x + long_min) + (-1) = x + long_max
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64\n" +
- "; CHECK: [[long_max:%\\w+]] = OpConstant [[long]] 9223372036854775807\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpIAdd [[long]] [[ld]] [[long_max]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpIAdd %long %2 %long_min\n" +
- "%4 = OpIAdd %long %3 %long_n1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true)
- ));
- INSTANTIATE_TEST_SUITE_P(MergeGenericAddSub, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: merge of add of sub
- // (a - b) + b => a
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: %6 = OpCopyObject [[float]] %3\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var0 = OpVariable %_ptr_float Function\n" +
- "%var1 = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %var0\n" +
- "%4 = OpLoad %float %var1\n" +
- "%5 = OpFSub %float %3 %4\n" +
- "%6 = OpFAdd %float %5 %4\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 6, true),
- // Test case 1: merge of add of sub
- // b + (a - b) => a
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: %6 = OpCopyObject [[float]] %3\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var0 = OpVariable %_ptr_float Function\n" +
- "%var1 = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %var0\n" +
- "%4 = OpLoad %float %var1\n" +
- "%5 = OpFSub %float %3 %4\n" +
- "%6 = OpFAdd %float %4 %5\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 6, true)
- ));
- INSTANTIATE_TEST_SUITE_P(FactorAddMul, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: factor of add of muls
- // (a * b) + (a * c) => a * (b + c)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[newadd:%\\w+]] = OpFAdd [[float]] %4 %5\n" +
- "; CHECK: %9 = OpFMul [[float]] %6 [[newadd]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var0 = OpVariable %_ptr_float Function\n" +
- "%var1 = OpVariable %_ptr_float Function\n" +
- "%var2 = OpVariable %_ptr_float Function\n" +
- "%4 = OpLoad %float %var0\n" +
- "%5 = OpLoad %float %var1\n" +
- "%6 = OpLoad %float %var2\n" +
- "%7 = OpFMul %float %6 %4\n" +
- "%8 = OpFMul %float %6 %5\n" +
- "%9 = OpFAdd %float %7 %8\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true),
- // Test case 1: factor of add of muls
- // (b * a) + (a * c) => a * (b + c)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[newadd:%\\w+]] = OpFAdd [[float]] %4 %5\n" +
- "; CHECK: %9 = OpFMul [[float]] %6 [[newadd]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var0 = OpVariable %_ptr_float Function\n" +
- "%var1 = OpVariable %_ptr_float Function\n" +
- "%var2 = OpVariable %_ptr_float Function\n" +
- "%4 = OpLoad %float %var0\n" +
- "%5 = OpLoad %float %var1\n" +
- "%6 = OpLoad %float %var2\n" +
- "%7 = OpFMul %float %4 %6\n" +
- "%8 = OpFMul %float %6 %5\n" +
- "%9 = OpFAdd %float %7 %8\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true),
- // Test case 2: factor of add of muls
- // (a * b) + (c * a) => a * (b + c)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[newadd:%\\w+]] = OpFAdd [[float]] %4 %5\n" +
- "; CHECK: %9 = OpFMul [[float]] %6 [[newadd]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var0 = OpVariable %_ptr_float Function\n" +
- "%var1 = OpVariable %_ptr_float Function\n" +
- "%var2 = OpVariable %_ptr_float Function\n" +
- "%4 = OpLoad %float %var0\n" +
- "%5 = OpLoad %float %var1\n" +
- "%6 = OpLoad %float %var2\n" +
- "%7 = OpFMul %float %6 %4\n" +
- "%8 = OpFMul %float %5 %6\n" +
- "%9 = OpFAdd %float %7 %8\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true),
- // Test case 3: factor of add of muls
- // (b * a) + (c * a) => a * (b + c)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[newadd:%\\w+]] = OpFAdd [[float]] %4 %5\n" +
- "; CHECK: %9 = OpFMul [[float]] %6 [[newadd]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var0 = OpVariable %_ptr_float Function\n" +
- "%var1 = OpVariable %_ptr_float Function\n" +
- "%var2 = OpVariable %_ptr_float Function\n" +
- "%4 = OpLoad %float %var0\n" +
- "%5 = OpLoad %float %var1\n" +
- "%6 = OpLoad %float %var2\n" +
- "%7 = OpFMul %float %4 %6\n" +
- "%8 = OpFMul %float %5 %6\n" +
- "%9 = OpFAdd %float %7 %8\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true)
- ));
- INSTANTIATE_TEST_SUITE_P(MergeSubTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: merge sub of negate
- // (-x) - 2 = -2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFNegate %float %2\n" +
- "%4 = OpFSub %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 1: merge sub of negate
- // 2 - (-x) = x + 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFNegate %float %2\n" +
- "%4 = OpFSub %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 2: merge sub of negate
- // (-x) - 2 = -2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_n2:%\\w+]] = OpConstant [[long]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpISub [[long]] [[long_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpSNegate %long %2\n" +
- "%4 = OpISub %long %3 %long_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 3: merge sub of negate
- // 2 - (-x) = x + 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_2:%\\w+]] = OpConstant [[long]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpIAdd [[long]] [[ld]] [[long_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpSNegate %long %2\n" +
- "%4 = OpISub %long %long_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 4: merge add of subtract
- // (x + 2) - 1 = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %2 %float_2\n" +
- "%4 = OpFSub %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 5: merge add of subtract
- // (2 + x) - 1 = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %float_2 %2\n" +
- "%4 = OpFSub %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 6: merge add of subtract
- // 2 - (x + 1) = 1 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_1]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %2 %float_1\n" +
- "%4 = OpFSub %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 7: merge add of subtract
- // 2 - (1 + x) = 1 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_1]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %float_1 %2\n" +
- "%4 = OpFSub %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 8: merge subtract of subtract
- // (x - 2) - 1 = x - 3
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_3:%\\w+]] = OpConstant [[float]] 3\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[ld]] [[float_3]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %2 %float_2\n" +
- "%4 = OpFSub %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 9: merge subtract of subtract
- // (2 - x) - 1 = 1 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_1]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %float_2 %2\n" +
- "%4 = OpFSub %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 10: merge subtract of subtract
- // 2 - (x - 1) = 3 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_3:%\\w+]] = OpConstant [[float]] 3\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_3]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %2 %float_1\n" +
- "%4 = OpFSub %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 11: merge subtract of subtract
- // 1 - (2 - x) = x + (-1)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n1:%\\w+]] = OpConstant [[float]] -1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_n1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %float_2 %2\n" +
- "%4 = OpFSub %float %float_1 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 12: merge subtract of subtract
- // 2 - (1 - x) = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %float_1 %2\n" +
- "%4 = OpFSub %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 13: merge subtract of subtract with mixed types.
- // 2 - (1 - x) = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int_1:%\\w+]] = OpConstant [[int]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpIAdd [[int]] [[ld]] [[int_1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpISub %int %uint_1 %2\n" +
- "%4 = OpISub %int %int_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 14: fold overflowing signed 32 bit isubs
- // (x - int_max) - 1 = x - int_min
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32\n" +
- "; CHECK: [[int_min:%\\w+]] = OpConstant [[int]] -2147483648\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpISub [[int]] [[ld]] [[int_min]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpISub %int %2 %int_max\n" +
- "%4 = OpISub %int %3 %int_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 15: fold overflowing signed 64 bit isubs
- // (x - long_max) - 1 = x - long_min
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64\n" +
- "; CHECK: [[long_min:%\\w+]] = OpConstant [[long]] -9223372036854775808\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpISub [[long]] [[ld]] [[long_min]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpISub %long %2 %long_max\n" +
- "%4 = OpISub %long %3 %long_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true)
- ));
- INSTANTIATE_TEST_SUITE_P(SelectFoldingTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Fold select with the same values for both sides
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int0:%\\w+]] = OpConstant [[int]] 0\n" +
- "; CHECK: %2 = OpCopyObject [[int]] [[int0]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_bool Function\n" +
- "%load = OpLoad %bool %n\n" +
- "%2 = OpSelect %int %load %100 %100\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 1: Fold select true to left side
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int0:%\\w+]] = OpConstant [[int]] 0\n" +
- "; CHECK: %2 = OpCopyObject [[int]] [[int0]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %bool %n\n" +
- "%2 = OpSelect %int %true %100 %n\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 2: Fold select false to right side
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int0:%\\w+]] = OpConstant [[int]] 0\n" +
- "; CHECK: %2 = OpCopyObject [[int]] [[int0]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %bool %n\n" +
- "%2 = OpSelect %int %false %n %100\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 3: Fold select null to right side
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int0:%\\w+]] = OpConstant [[int]] 0\n" +
- "; CHECK: %2 = OpCopyObject [[int]] [[int0]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpSelect %int %bool_null %load %100\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 4: vector null
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[v2int:%\\w+]] = OpTypeVector [[int]] 2\n" +
- "; CHECK: [[int2:%\\w+]] = OpConstant [[int]] 2\n" +
- "; CHECK: [[v2int2_2:%\\w+]] = OpConstantComposite [[v2int]] [[int2]] [[int2]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2int]] [[v2int2_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%load = OpLoad %v2int %n\n" +
- "%2 = OpSelect %v2int %v2bool_null %load %v2int_2_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 5: vector select
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[v2int:%\\w+]] = OpTypeVector [[int]] 2\n" +
- "; CHECK: %4 = OpVectorShuffle [[v2int]] %2 %3 0 3\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%m = OpVariable %_ptr_v2int Function\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%2 = OpLoad %v2int %n\n" +
- "%3 = OpLoad %v2int %n\n" +
- "%4 = OpSelect %v2int %v2bool_true_false %2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 6: vector select
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[v2int:%\\w+]] = OpTypeVector [[int]] 2\n" +
- "; CHECK: %4 = OpVectorShuffle [[v2int]] %2 %3 2 1\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%m = OpVariable %_ptr_v2int Function\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%2 = OpLoad %v2int %n\n" +
- "%3 = OpLoad %v2int %n\n" +
- "%4 = OpSelect %v2int %v2bool_false_true %2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true)
- ));
- INSTANTIATE_TEST_SUITE_P(CompositeExtractOrInsertMatchingTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Extracting from result of consecutive shuffles of differing
- // size.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: %5 = OpCompositeExtract [[int]] %2 2\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4int Function\n" +
- "%2 = OpLoad %v4int %n\n" +
- "%3 = OpVectorShuffle %v2int %2 %2 2 3\n" +
- "%4 = OpVectorShuffle %v4int %2 %3 0 4 2 5\n" +
- "%5 = OpCompositeExtract %int %4 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, true),
- // Test case 1: Extracting from result of vector shuffle of differing
- // input and result sizes.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: %4 = OpCompositeExtract [[int]] %2 2\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4int Function\n" +
- "%2 = OpLoad %v4int %n\n" +
- "%3 = OpVectorShuffle %v2int %2 %2 2 3\n" +
- "%4 = OpCompositeExtract %int %3 0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 2: Extracting from result of vector shuffle of differing
- // input and result sizes.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: %4 = OpCompositeExtract [[int]] %2 3\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4int Function\n" +
- "%2 = OpLoad %v4int %n\n" +
- "%3 = OpVectorShuffle %v2int %2 %2 2 3\n" +
- "%4 = OpCompositeExtract %int %3 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 3: Using fmix feeding extract with a 1 in the a position.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v4double:%\\w+]] = OpTypeVector [[double]] 4\n" +
- "; CHECK: [[ptr_v4double:%\\w+]] = OpTypePointer Function [[v4double]]\n" +
- "; CHECK: [[m:%\\w+]] = OpVariable [[ptr_v4double]] Function\n" +
- "; CHECK: [[n:%\\w+]] = OpVariable [[ptr_v4double]] Function\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v4double]] [[n]]\n" +
- "; CHECK: %5 = OpCompositeExtract [[double]] [[ld]] 1\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%m = OpVariable %_ptr_v4double Function\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%2 = OpLoad %v4double %m\n" +
- "%3 = OpLoad %v4double %n\n" +
- "%4 = OpExtInst %v4double %1 FMix %2 %3 %v4double_0_1_0_0\n" +
- "%5 = OpCompositeExtract %double %4 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, true),
- // Test case 4: Using fmix feeding extract with a 0 in the a position.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v4double:%\\w+]] = OpTypeVector [[double]] 4\n" +
- "; CHECK: [[ptr_v4double:%\\w+]] = OpTypePointer Function [[v4double]]\n" +
- "; CHECK: [[m:%\\w+]] = OpVariable [[ptr_v4double]] Function\n" +
- "; CHECK: [[n:%\\w+]] = OpVariable [[ptr_v4double]] Function\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v4double]] [[m]]\n" +
- "; CHECK: %5 = OpCompositeExtract [[double]] [[ld]] 2\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%m = OpVariable %_ptr_v4double Function\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%2 = OpLoad %v4double %m\n" +
- "%3 = OpLoad %v4double %n\n" +
- "%4 = OpExtInst %v4double %1 FMix %2 %3 %v4double_0_1_0_0\n" +
- "%5 = OpCompositeExtract %double %4 2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, true),
- // Test case 5: Using fmix feeding extract with a null for the alpha
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v4double:%\\w+]] = OpTypeVector [[double]] 4\n" +
- "; CHECK: [[ptr_v4double:%\\w+]] = OpTypePointer Function [[v4double]]\n" +
- "; CHECK: [[m:%\\w+]] = OpVariable [[ptr_v4double]] Function\n" +
- "; CHECK: [[n:%\\w+]] = OpVariable [[ptr_v4double]] Function\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v4double]] [[m]]\n" +
- "; CHECK: %5 = OpCompositeExtract [[double]] [[ld]] 0\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%m = OpVariable %_ptr_v4double Function\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%2 = OpLoad %v4double %m\n" +
- "%3 = OpLoad %v4double %n\n" +
- "%4 = OpExtInst %v4double %1 FMix %2 %3 %v4double_null\n" +
- "%5 = OpCompositeExtract %double %4 0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, true),
- // Test case 6: Don't fold: Using fmix feeding extract with 0.5 in the a
- // position.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%m = OpVariable %_ptr_v4double Function\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%2 = OpLoad %v4double %m\n" +
- "%3 = OpLoad %v4double %n\n" +
- "%4 = OpExtInst %v4double %1 FMix %2 %3 %v4double_1_1_1_0p5\n" +
- "%5 = OpCompositeExtract %double %4 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, false),
- // Test case 7: Extracting the undefined literal value from a vector
- // shuffle.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: %4 = OpUndef [[int]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4int Function\n" +
- "%2 = OpLoad %v4int %n\n" +
- "%3 = OpVectorShuffle %v2int %2 %2 2 4294967295\n" +
- "%4 = OpCompositeExtract %int %3 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 8: Inserting every element of a vector turns into a composite construct.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK-DAG: [[v4:%\\w+]] = OpTypeVector [[int]] 4\n" +
- "; CHECK-DAG: [[int1:%\\w+]] = OpConstant [[int]] 1\n" +
- "; CHECK-DAG: [[int2:%\\w+]] = OpConstant [[int]] 2\n" +
- "; CHECK-DAG: [[int3:%\\w+]] = OpConstant [[int]] 3\n" +
- "; CHECK: [[construct:%\\w+]] = OpCompositeConstruct [[v4]] %100 [[int1]] [[int2]] [[int3]]\n" +
- "; CHECK: %5 = OpCopyObject [[v4]] [[construct]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeInsert %v4int %100 %v4int_undef 0\n" +
- "%3 = OpCompositeInsert %v4int %int_1 %2 1\n" +
- "%4 = OpCompositeInsert %v4int %int_2 %3 2\n" +
- "%5 = OpCompositeInsert %v4int %int_3 %4 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, true),
- // Test case 9: Inserting every element of a vector turns into a composite construct in a different order.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK-DAG: [[v4:%\\w+]] = OpTypeVector [[int]] 4\n" +
- "; CHECK-DAG: [[int1:%\\w+]] = OpConstant [[int]] 1\n" +
- "; CHECK-DAG: [[int2:%\\w+]] = OpConstant [[int]] 2\n" +
- "; CHECK-DAG: [[int3:%\\w+]] = OpConstant [[int]] 3\n" +
- "; CHECK: [[construct:%\\w+]] = OpCompositeConstruct [[v4]] %100 [[int1]] [[int2]] [[int3]]\n" +
- "; CHECK: %5 = OpCopyObject [[v4]] [[construct]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeInsert %v4int %100 %v4int_undef 0\n" +
- "%4 = OpCompositeInsert %v4int %int_2 %2 2\n" +
- "%3 = OpCompositeInsert %v4int %int_1 %4 1\n" +
- "%5 = OpCompositeInsert %v4int %int_3 %3 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, true),
- // Test case 10: Check multiple inserts to the same position are handled correctly.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK-DAG: [[v4:%\\w+]] = OpTypeVector [[int]] 4\n" +
- "; CHECK-DAG: [[int1:%\\w+]] = OpConstant [[int]] 1\n" +
- "; CHECK-DAG: [[int2:%\\w+]] = OpConstant [[int]] 2\n" +
- "; CHECK-DAG: [[int3:%\\w+]] = OpConstant [[int]] 3\n" +
- "; CHECK: [[construct:%\\w+]] = OpCompositeConstruct [[v4]] %100 [[int1]] [[int2]] [[int3]]\n" +
- "; CHECK: %6 = OpCopyObject [[v4]] [[construct]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeInsert %v4int %100 %v4int_undef 0\n" +
- "%3 = OpCompositeInsert %v4int %int_2 %2 2\n" +
- "%4 = OpCompositeInsert %v4int %int_4 %3 1\n" +
- "%5 = OpCompositeInsert %v4int %int_1 %4 1\n" +
- "%6 = OpCompositeInsert %v4int %int_3 %5 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 6, true),
- // Test case 11: The last indexes are 0 and 1, but they have different first indexes. This should not be folded.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeInsert %m2x2int %100 %m2x2int_undef 0 0\n" +
- "%3 = OpCompositeInsert %m2x2int %int_1 %2 1 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, false),
- // Test case 12: Don't fold when there is a partial insertion.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeInsert %m2x2int %v2int_1_0 %m2x2int_undef 0\n" +
- "%3 = OpCompositeInsert %m2x2int %int_4 %2 0 0\n" +
- "%4 = OpCompositeInsert %m2x2int %v2int_2_3 %3 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, false),
- // Test case 13: Insert into a column of a matrix
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK-DAG: [[v2:%\\w+]] = OpTypeVector [[int]] 2\n" +
- "; CHECK: [[m2x2:%\\w+]] = OpTypeMatrix [[v2]] 2\n" +
- "; CHECK-DAG: [[m2x2_undef:%\\w+]] = OpUndef [[m2x2]]\n" +
- "; CHECK-DAG: [[int1:%\\w+]] = OpConstant [[int]] 1\n" +
- // We keep this insert in the chain. DeadInsertElimPass should remove it.
- "; CHECK: [[insert:%\\w+]] = OpCompositeInsert [[m2x2]] %100 [[m2x2_undef]] 0 0\n" +
- "; CHECK: [[construct:%\\w+]] = OpCompositeConstruct [[v2]] %100 [[int1]]\n" +
- "; CHECK: %3 = OpCompositeInsert [[m2x2]] [[construct]] [[insert]] 0\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeInsert %m2x2int %100 %m2x2int_undef 0 0\n" +
- "%3 = OpCompositeInsert %m2x2int %int_1 %2 0 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, true),
- // Test case 14: Insert all elements of the matrix.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK-DAG: [[v2:%\\w+]] = OpTypeVector [[int]] 2\n" +
- "; CHECK: [[m2x2:%\\w+]] = OpTypeMatrix [[v2]] 2\n" +
- "; CHECK-DAG: [[m2x2_undef:%\\w+]] = OpUndef [[m2x2]]\n" +
- "; CHECK-DAG: [[int1:%\\w+]] = OpConstant [[int]] 1\n" +
- "; CHECK-DAG: [[int2:%\\w+]] = OpConstant [[int]] 2\n" +
- "; CHECK-DAG: [[int3:%\\w+]] = OpConstant [[int]] 3\n" +
- "; CHECK: [[c0:%\\w+]] = OpCompositeConstruct [[v2]] %100 [[int1]]\n" +
- "; CHECK: [[c1:%\\w+]] = OpCompositeConstruct [[v2]] [[int2]] [[int3]]\n" +
- "; CHECK: [[matrix:%\\w+]] = OpCompositeConstruct [[m2x2]] [[c0]] [[c1]]\n" +
- "; CHECK: %5 = OpCopyObject [[m2x2]] [[matrix]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeConstruct %v2int %100 %int_1\n" +
- "%3 = OpCompositeInsert %m2x2int %2 %m2x2int_undef 0\n" +
- "%4 = OpCompositeInsert %m2x2int %int_2 %3 1 0\n" +
- "%5 = OpCompositeInsert %m2x2int %int_3 %4 1 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, true),
- // Test case 15: Replace construct with extract when reconstructing a member
- // of another object.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[v2:%\\w+]] = OpTypeVector [[int]] 2\n" +
- "; CHECK: [[m2x2:%\\w+]] = OpTypeMatrix [[v2]] 2\n" +
- "; CHECK: [[m2x2_undef:%\\w+]] = OpUndef [[m2x2]]\n" +
- "; CHECK: %5 = OpCompositeExtract [[v2]] [[m2x2_undef]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%3 = OpCompositeExtract %int %m2x2int_undef 1 0\n" +
- "%4 = OpCompositeExtract %int %m2x2int_undef 1 1\n" +
- "%5 = OpCompositeConstruct %v2int %3 %4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, true),
- // Test case 16: Don't fold when type cannot be deduced to a constant.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%4 = OpCompositeInsert %struct_v2int_int_int %int_1 %struct_v2int_int_int_null 2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, false),
- // Test case 17: Don't fold when index into composite is out of bounds.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%4 = OpCompositeExtract %int %struct_v2int_int_int 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, false),
- // Test case 18: Fold when every element of an array is inserted.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int2:%\\w+]] = OpConstant [[int]] 2\n" +
- "; CHECK-DAG: [[arr_type:%\\w+]] = OpTypeArray [[int]] [[int2]]\n" +
- "; CHECK-DAG: [[int10:%\\w+]] = OpConstant [[int]] 10\n" +
- "; CHECK-DAG: [[int1:%\\w+]] = OpConstant [[int]] 1\n" +
- "; CHECK: [[construct:%\\w+]] = OpCompositeConstruct [[arr_type]] [[int10]] [[int1]]\n" +
- "; CHECK: %5 = OpCopyObject [[arr_type]] [[construct]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%4 = OpCompositeInsert %int_arr_2 %int_10 %int_arr_2_undef 0\n" +
- "%5 = OpCompositeInsert %int_arr_2 %int_1 %4 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, true),
- // Test case 19: Don't fold for isomorphic structs
- InstructionFoldingCase<bool>(
- Header() +
- "%structA = OpTypeStruct %ulong\n" +
- "%structB = OpTypeStruct %ulong\n" +
- "%structC = OpTypeStruct %structB\n" +
- "%struct_a_undef = OpUndef %structA\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%3 = OpCompositeExtract %ulong %struct_a_undef 0\n" +
- "%4 = OpCompositeConstruct %structB %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, false)
- ));
- INSTANTIATE_TEST_SUITE_P(DotProductMatchingTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Using OpDot to extract last element.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: %3 = OpCompositeExtract [[float]] %2 3\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4float Function\n" +
- "%2 = OpLoad %v4float %n\n" +
- "%3 = OpDot %float %2 %v4float_0_0_0_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, true),
- // Test case 1: Using OpDot to extract last element.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: %3 = OpCompositeExtract [[float]] %2 3\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4float Function\n" +
- "%2 = OpLoad %v4float %n\n" +
- "%3 = OpDot %float %v4float_0_0_0_1 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, true),
- // Test case 2: Using OpDot to extract second element.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: %3 = OpCompositeExtract [[float]] %2 1\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4float Function\n" +
- "%2 = OpLoad %v4float %n\n" +
- "%3 = OpDot %float %v4float_0_1_0_0 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, true),
- // Test case 3: Using OpDot to extract last element.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: %3 = OpCompositeExtract [[double]] %2 3\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%2 = OpLoad %v4double %n\n" +
- "%3 = OpDot %double %2 %v4double_0_0_0_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, true),
- // Test case 4: Using OpDot to extract last element.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: %3 = OpCompositeExtract [[double]] %2 3\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%2 = OpLoad %v4double %n\n" +
- "%3 = OpDot %double %v4double_0_0_0_1 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, true),
- // Test case 5: Using OpDot to extract second element.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: %3 = OpCompositeExtract [[double]] %2 1\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%2 = OpLoad %v4double %n\n" +
- "%3 = OpDot %double %v4double_0_1_0_0 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, true)
- ));
- INSTANTIATE_TEST_SUITE_P(VectorShuffleMatchingTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Using OpDot to extract last element.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[v2int:%\\w+]] = OpTypeVector [[int]] 2{{[[:space:]]}}\n" +
- "; CHECK: [[null:%\\w+]] = OpConstantNull [[v2int]]\n" +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: %3 = OpVectorShuffle [[v2int]] [[null]] {{%\\w+}} 4294967295 2\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpVectorShuffle %v2int %v2int_null %v2int_2_3 3 0xFFFFFFFF \n" +
- "%3 = OpVectorShuffle %v2int %2 %v2int_2_3 1 2 \n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, true)
- ));
- // Issue #5658: The Adreno compiler does not handle 16-bit FMA instructions well.
- // We want to avoid this by not generating FMA. We decided to never generate
- // FMAs because, from a SPIR-V perspective, it is neutral. The ICD can generate
- // the FMA if it wants. The simplest code is no code.
- INSTANTIATE_TEST_SUITE_P(FmaGenerationMatchingTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Don't fold (x * y) + a
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%a = OpVariable %_ptr_float Function\n" +
- "%lx = OpLoad %float %x\n" +
- "%ly = OpLoad %float %y\n" +
- "%mul = OpFMul %float %lx %ly\n" +
- "%la = OpLoad %float %a\n" +
- "%3 = OpFAdd %float %mul %la\n" +
- "OpStore %a %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, false),
- // Test case 1: Don't fold a + (x * y)
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%a = OpVariable %_ptr_float Function\n" +
- "%lx = OpLoad %float %x\n" +
- "%ly = OpLoad %float %y\n" +
- "%mul = OpFMul %float %lx %ly\n" +
- "%la = OpLoad %float %a\n" +
- "%3 = OpFAdd %float %la %mul\n" +
- "OpStore %a %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, false),
- // Test case 2: Don't fold (x * y) + a with vectors
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_v4float Function\n" +
- "%y = OpVariable %_ptr_v4float Function\n" +
- "%a = OpVariable %_ptr_v4float Function\n" +
- "%lx = OpLoad %v4float %x\n" +
- "%ly = OpLoad %v4float %y\n" +
- "%mul = OpFMul %v4float %lx %ly\n" +
- "%la = OpLoad %v4float %a\n" +
- "%3 = OpFAdd %v4float %mul %la\n" +
- "OpStore %a %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3,false),
- // Test case 3: Don't fold a + (x * y) with vectors
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%a = OpVariable %_ptr_float Function\n" +
- "%lx = OpLoad %float %x\n" +
- "%ly = OpLoad %float %y\n" +
- "%mul = OpFMul %float %lx %ly\n" +
- "%la = OpLoad %float %a\n" +
- "%3 = OpFAdd %float %la %mul\n" +
- "OpStore %a %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, false),
- // Test 4: Don't fold if the multiple is marked no contract.
- InstructionFoldingCase<bool>(
- std::string() +
- "OpCapability Shader\n" +
- "OpMemoryModel Logical GLSL450\n" +
- "OpEntryPoint Fragment %main \"main\"\n" +
- "OpExecutionMode %main OriginUpperLeft\n" +
- "OpSource GLSL 140\n" +
- "OpName %main \"main\"\n" +
- "OpDecorate %mul NoContraction\n" +
- "%void = OpTypeVoid\n" +
- "%void_func = OpTypeFunction %void\n" +
- "%bool = OpTypeBool\n" +
- "%float = OpTypeFloat 32\n" +
- "%_ptr_float = OpTypePointer Function %float\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%a = OpVariable %_ptr_float Function\n" +
- "%lx = OpLoad %float %x\n" +
- "%ly = OpLoad %float %y\n" +
- "%mul = OpFMul %float %lx %ly\n" +
- "%la = OpLoad %float %a\n" +
- "%3 = OpFAdd %float %mul %la\n" +
- "OpStore %a %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, false),
- // Test 5: Don't fold if the add is marked no contract.
- InstructionFoldingCase<bool>(
- std::string() +
- "OpCapability Shader\n" +
- "OpMemoryModel Logical GLSL450\n" +
- "OpEntryPoint Fragment %main \"main\"\n" +
- "OpExecutionMode %main OriginUpperLeft\n" +
- "OpSource GLSL 140\n" +
- "OpName %main \"main\"\n" +
- "OpDecorate %3 NoContraction\n" +
- "%void = OpTypeVoid\n" +
- "%void_func = OpTypeFunction %void\n" +
- "%bool = OpTypeBool\n" +
- "%float = OpTypeFloat 32\n" +
- "%_ptr_float = OpTypePointer Function %float\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%a = OpVariable %_ptr_float Function\n" +
- "%lx = OpLoad %float %x\n" +
- "%ly = OpLoad %float %y\n" +
- "%mul = OpFMul %float %lx %ly\n" +
- "%la = OpLoad %float %a\n" +
- "%3 = OpFAdd %float %mul %la\n" +
- "OpStore %a %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, false),
- // Test case 6: Don't fold (x * y) - a
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%a = OpVariable %_ptr_float Function\n" +
- "%lx = OpLoad %float %x\n" +
- "%ly = OpLoad %float %y\n" +
- "%mul = OpFMul %float %lx %ly\n" +
- "%la = OpLoad %float %a\n" +
- "%3 = OpFSub %float %mul %la\n" +
- "OpStore %a %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, false),
- // Test case 7: Don't fold a - (x * y)
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%a = OpVariable %_ptr_float Function\n" +
- "%lx = OpLoad %float %x\n" +
- "%ly = OpLoad %float %y\n" +
- "%mul = OpFMul %float %lx %ly\n" +
- "%la = OpLoad %float %a\n" +
- "%3 = OpFSub %float %la %mul\n" +
- "OpStore %a %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, false)
- ));
- using MatchingInstructionWithNoResultFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<bool>>;
- // Test folding instructions that do not have a result. The instruction
- // that will be folded is the last instruction before the return. If there
- // are multiple returns, there is not guarantee which one is used.
- TEST_P(MatchingInstructionWithNoResultFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) = FoldInstruction(tc.test_body, tc.id_to_fold,SPV_ENV_UNIVERSAL_1_1);
- // Find the instruction to test.
- EXPECT_EQ(inst != nullptr, tc.expected_result);
- if (inst != nullptr) {
- Match(tc.test_body, context.get());
- }
- }
- INSTANTIATE_TEST_SUITE_P(StoreMatchingTest, MatchingInstructionWithNoResultFoldingTest,
- ::testing::Values(
- // Test case 0: Remove store of undef.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: OpLabel\n" +
- "; CHECK-NOT: OpStore\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%undef = OpUndef %v4double\n" +
- "OpStore %n %undef\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 0 /* OpStore */, true),
- // Test case 1: Keep volatile store.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v4double Function\n" +
- "%undef = OpUndef %v4double\n" +
- "OpStore %n %undef Volatile\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 0 /* OpStore */, false)
- ));
- INSTANTIATE_TEST_SUITE_P(VectorShuffleMatchingTest, MatchingInstructionWithNoResultFoldingTest,
- ::testing::Values(
- // Test case 0: Basic test 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} %7 %5 2 3 6 7\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v4double %5 %6 2 3 4 5\n" +
- "%9 = OpVectorShuffle %v4double %7 %8 2 3 4 5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true),
- // Test case 1: Basic test 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} %6 %7 0 1 4 5\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v4double %5 %6 2 3 4 5\n" +
- "%9 = OpVectorShuffle %v4double %8 %7 2 3 4 5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true),
- // Test case 2: Basic test 3
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} %5 %7 3 2 4 5\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v4double %5 %6 2 3 4 5\n" +
- "%9 = OpVectorShuffle %v4double %8 %7 1 0 4 5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true),
- // Test case 3: Basic test 4
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} %7 %6 2 3 5 4\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v4double %5 %6 2 3 4 5\n" +
- "%9 = OpVectorShuffle %v4double %7 %8 2 3 7 6\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true),
- // Test case 4: Don't fold, need both operands of the feeder.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v4double %5 %6 2 3 4 5\n" +
- "%9 = OpVectorShuffle %v4double %7 %8 2 3 7 5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, false),
- // Test case 5: Don't fold, need both operands of the feeder.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v4double %5 %6 2 3 4 5\n" +
- "%9 = OpVectorShuffle %v4double %8 %7 2 0 7 5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, false),
- // Test case 6: Fold, need both operands of the feeder, but they are the same.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} %5 %7 0 2 7 5\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v4double %5 %5 2 3 4 5\n" +
- "%9 = OpVectorShuffle %v4double %8 %7 2 0 7 5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true),
- // Test case 7: Fold, need both operands of the feeder, but they are the same.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} %7 %5 2 0 5 7\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v4double %5 %5 2 3 4 5\n" +
- "%9 = OpVectorShuffle %v4double %7 %8 2 0 7 5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true),
- // Test case 8: Replace first operand with a smaller vector.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} %5 %7 0 0 5 3\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v2double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v2double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v4double %5 %5 0 1 2 3\n" +
- "%9 = OpVectorShuffle %v4double %8 %7 2 0 7 5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true),
- // Test case 9: Replace first operand with a larger vector.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} %5 %7 3 0 7 5\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v2double %5 %5 0 3\n" +
- "%9 = OpVectorShuffle %v4double %8 %7 1 0 5 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true),
- // Test case 10: Replace unused operand with null.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v4double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: [[null:%\\w+]] = OpConstantNull [[v4double]]\n" +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} [[null]] %7 4 2 5 3\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v2double %5 %5 0 3\n" +
- "%9 = OpVectorShuffle %v4double %8 %7 4 2 5 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true),
- // Test case 11: Replace unused operand with null.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v4double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: [[null:%\\w+]] = OpConstantNull [[v4double]]\n" +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} [[null]] %5 2 2 5 5\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%8 = OpVectorShuffle %v2double %5 %5 0 3\n" +
- "%9 = OpVectorShuffle %v4double %8 %8 2 2 3 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true),
- // Test case 12: Replace unused operand with null.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v4double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: [[null:%\\w+]] = OpConstantNull [[v4double]]\n" +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} %7 [[null]] 2 0 1 3\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v2double %5 %5 0 3\n" +
- "%9 = OpVectorShuffle %v4double %7 %8 2 0 1 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true),
- // Test case 13: Shuffle with undef literal.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v4double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} %7 {{%\\w+}} 2 0 1 4294967295\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v2double %5 %5 0 1\n" +
- "%9 = OpVectorShuffle %v4double %7 %8 2 0 1 4294967295\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true),
- // Test case 14: Shuffle with undef literal and change size of first input vector.
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v4double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: OpVectorShuffle\n" +
- "; CHECK: OpVectorShuffle {{%\\w+}} %5 %7 0 1 4 4294967295\n" +
- "; CHECK: OpReturn\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVariable %_ptr_v4double Function\n" +
- "%3 = OpVariable %_ptr_v4double Function\n" +
- "%4 = OpVariable %_ptr_v4double Function\n" +
- "%5 = OpLoad %v4double %2\n" +
- "%6 = OpLoad %v4double %3\n" +
- "%7 = OpLoad %v4double %4\n" +
- "%8 = OpVectorShuffle %v2double %5 %5 0 1\n" +
- "%9 = OpVectorShuffle %v4double %8 %7 0 1 2 4294967295\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 9, true)
- ));
- using EntryPointFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<bool>>;
- TEST_P(EntryPointFoldingTest, Case) {
- const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
- // Find the first entry point. That is the instruction we want to fold.
- Instruction* inst = nullptr;
- ASSERT_FALSE(context->module()->entry_points().empty());
- inst = &*context->module()->entry_points().begin();
- assert(inst && "Invalid test. Could not find entry point instruction to fold.");
- std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- EXPECT_EQ(succeeded, tc.expected_result);
- if (succeeded) {
- Match(tc.test_body, context.get());
- }
- }
- INSTANTIATE_TEST_SUITE_P(OpEntryPointFoldingTest, EntryPointFoldingTest,
- ::testing::Values(
- // Test case 0: Basic test 1
- InstructionFoldingCase<bool>(std::string() +
- "; CHECK: OpEntryPoint Fragment %2 \"main\" %3\n" +
- "OpCapability Shader\n" +
- "%1 = OpExtInstImport \"GLSL.std.450\"\n" +
- "OpMemoryModel Logical GLSL450\n" +
- "OpEntryPoint Fragment %2 \"main\" %3 %3 %3\n" +
- "OpExecutionMode %2 OriginUpperLeft\n" +
- "OpSource GLSL 430\n" +
- "OpDecorate %3 Location 0\n" +
- "%void = OpTypeVoid\n" +
- "%5 = OpTypeFunction %void\n" +
- "%float = OpTypeFloat 32\n" +
- "%v4float = OpTypeVector %float 4\n" +
- "%_ptr_Output_v4float = OpTypePointer Output %v4float\n" +
- "%3 = OpVariable %_ptr_Output_v4float Output\n" +
- "%int = OpTypeInt 32 1\n" +
- "%int_0 = OpConstant %int 0\n" +
- "%_ptr_PushConstant_v4float = OpTypePointer PushConstant %v4float\n" +
- "%2 = OpFunction %void None %5\n" +
- "%12 = OpLabel\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true),
- InstructionFoldingCase<bool>(std::string() +
- "; CHECK: OpEntryPoint Fragment %2 \"main\" %3 %4\n" +
- "OpCapability Shader\n" +
- "%1 = OpExtInstImport \"GLSL.std.450\"\n" +
- "OpMemoryModel Logical GLSL450\n" +
- "OpEntryPoint Fragment %2 \"main\" %3 %4 %3\n" +
- "OpExecutionMode %2 OriginUpperLeft\n" +
- "OpSource GLSL 430\n" +
- "OpDecorate %3 Location 0\n" +
- "%void = OpTypeVoid\n" +
- "%5 = OpTypeFunction %void\n" +
- "%float = OpTypeFloat 32\n" +
- "%v4float = OpTypeVector %float 4\n" +
- "%_ptr_Output_v4float = OpTypePointer Output %v4float\n" +
- "%3 = OpVariable %_ptr_Output_v4float Output\n" +
- "%4 = OpVariable %_ptr_Output_v4float Output\n" +
- "%int = OpTypeInt 32 1\n" +
- "%int_0 = OpConstant %int 0\n" +
- "%_ptr_PushConstant_v4float = OpTypePointer PushConstant %v4float\n" +
- "%2 = OpFunction %void None %5\n" +
- "%12 = OpLabel\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true),
- InstructionFoldingCase<bool>(std::string() +
- "; CHECK: OpEntryPoint Fragment %2 \"main\" %4 %3\n" +
- "OpCapability Shader\n" +
- "%1 = OpExtInstImport \"GLSL.std.450\"\n" +
- "OpMemoryModel Logical GLSL450\n" +
- "OpEntryPoint Fragment %2 \"main\" %4 %4 %3\n" +
- "OpExecutionMode %2 OriginUpperLeft\n" +
- "OpSource GLSL 430\n" +
- "OpDecorate %3 Location 0\n" +
- "%void = OpTypeVoid\n" +
- "%5 = OpTypeFunction %void\n" +
- "%float = OpTypeFloat 32\n" +
- "%v4float = OpTypeVector %float 4\n" +
- "%_ptr_Output_v4float = OpTypePointer Output %v4float\n" +
- "%3 = OpVariable %_ptr_Output_v4float Output\n" +
- "%4 = OpVariable %_ptr_Output_v4float Output\n" +
- "%int = OpTypeInt 32 1\n" +
- "%int_0 = OpConstant %int 0\n" +
- "%_ptr_PushConstant_v4float = OpTypePointer PushConstant %v4float\n" +
- "%2 = OpFunction %void None %5\n" +
- "%12 = OpLabel\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true)
- ));
- using SPV14FoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<bool>>;
- TEST_P(SPV14FoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) = FoldInstruction(tc.test_body, tc.id_to_fold,SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(inst != nullptr, tc.expected_result);
- if (inst != nullptr) {
- Match(tc.test_body, context.get());
- }
- }
- INSTANTIATE_TEST_SUITE_P(SPV14FoldingTest, SPV14FoldingTest,
- ::testing::Values(
- // Test case 0: select vectors with scalar condition.
- InstructionFoldingCase<bool>(std::string() +
- "; CHECK-NOT: OpSelect\n" +
- "; CHECK: %3 = OpCopyObject {{%\\w+}} %1\n" +
- "OpCapability Shader\n" +
- "OpCapability Linkage\n" +
- "%void = OpTypeVoid\n" +
- "%bool = OpTypeBool\n" +
- "%true = OpConstantTrue %bool\n" +
- "%int = OpTypeInt 32 0\n" +
- "%int4 = OpTypeVector %int 4\n" +
- "%int_0 = OpConstant %int 0\n" +
- "%int_1 = OpConstant %int 1\n" +
- "%1 = OpUndef %int4\n" +
- "%2 = OpUndef %int4\n" +
- "%void_fn = OpTypeFunction %void\n" +
- "%func = OpFunction %void None %void_fn\n" +
- "%entry = OpLabel\n" +
- "%3 = OpSelect %int4 %true %1 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 3, true),
- // Test case 1: select struct with scalar condition.
- InstructionFoldingCase<bool>(std::string() +
- "; CHECK-NOT: OpSelect\n" +
- "; CHECK: %3 = OpCopyObject {{%\\w+}} %2\n" +
- "OpCapability Shader\n" +
- "OpCapability Linkage\n" +
- "%void = OpTypeVoid\n" +
- "%bool = OpTypeBool\n" +
- "%true = OpConstantFalse %bool\n" +
- "%int = OpTypeInt 32 0\n" +
- "%struct = OpTypeStruct %int %int %int %int\n" +
- "%int_0 = OpConstant %int 0\n" +
- "%int_1 = OpConstant %int 1\n" +
- "%1 = OpUndef %struct\n" +
- "%2 = OpUndef %struct\n" +
- "%void_fn = OpTypeFunction %void\n" +
- "%func = OpFunction %void None %void_fn\n" +
- "%entry = OpLabel\n" +
- "%3 = OpSelect %struct %true %1 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 3, true),
- // Test case 1: select array with scalar condition.
- InstructionFoldingCase<bool>(std::string() +
- "; CHECK-NOT: OpSelect\n" +
- "; CHECK: %3 = OpCopyObject {{%\\w+}} %2\n" +
- "OpCapability Shader\n" +
- "OpCapability Linkage\n" +
- "%void = OpTypeVoid\n" +
- "%bool = OpTypeBool\n" +
- "%true = OpConstantFalse %bool\n" +
- "%int = OpTypeInt 32 0\n" +
- "%int_0 = OpConstant %int 0\n" +
- "%int_1 = OpConstant %int 1\n" +
- "%int_4 = OpConstant %int 4\n" +
- "%array = OpTypeStruct %int %int %int %int\n" +
- "%1 = OpUndef %array\n" +
- "%2 = OpUndef %array\n" +
- "%void_fn = OpTypeFunction %void\n" +
- "%func = OpFunction %void None %void_fn\n" +
- "%entry = OpLabel\n" +
- "%3 = OpSelect %array %true %1 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 3, true)
- ));
- std::string FloatControlsHeader(const std::string& capabilities) {
- std::string header = R"(
- OpCapability Shader
- )" + capabilities + R"(
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %float_1 = OpConstant %float 1
- %void_fn = OpTypeFunction %void
- %func = OpFunction %void None %void_fn
- %entry = OpLabel
- )";
- return header;
- }
- using FloatControlsFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<bool>>;
- TEST_P(FloatControlsFoldingTest, Case) {
- const auto& tc = GetParam();
- std::unique_ptr<IRContext> context;
- Instruction* inst;
- std::tie(context, inst) = FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_4);
- EXPECT_EQ(inst != nullptr, tc.expected_result);
- if (inst != nullptr) {
- Match(tc.test_body, context.get());
- }
- }
- INSTANTIATE_TEST_SUITE_P(FloatControlsFoldingTest, FloatControlsFoldingTest,
- ::testing::Values(
- // Test case 0: no folding with DenormPreserve
- InstructionFoldingCase<bool>(FloatControlsHeader("OpCapability DenormPreserve") +
- "%1 = OpFAdd %float %float_0 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 1, false),
- // Test case 1: no folding with DenormFlushToZero
- InstructionFoldingCase<bool>(FloatControlsHeader("OpCapability DenormFlushToZero") +
- "%1 = OpFAdd %float %float_0 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 1, false),
- // Test case 2: no folding with SignedZeroInfNanPreserve
- InstructionFoldingCase<bool>(FloatControlsHeader("OpCapability SignedZeroInfNanPreserve") +
- "%1 = OpFAdd %float %float_0 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 1, false),
- // Test case 3: no folding with RoundingModeRTE
- InstructionFoldingCase<bool>(FloatControlsHeader("OpCapability RoundingModeRTE") +
- "%1 = OpFAdd %float %float_0 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 1, false),
- // Test case 4: no folding with RoundingModeRTZ
- InstructionFoldingCase<bool>(FloatControlsHeader("OpCapability RoundingModeRTZ") +
- "%1 = OpFAdd %float %float_0 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 1, false)
- ));
- std::string ImageOperandsTestBody(const std::string& image_instruction) {
- std::string body = R"(
- OpCapability Shader
- OpCapability ImageGatherExtended
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %Texture DescriptorSet 0
- OpDecorate %Texture Binding 0
- %int = OpTypeInt 32 1
- %int_n1 = OpConstant %int -1
- %5 = OpConstant %int 0
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
- %type_sampled_image = OpTypeSampledImage %type_2d_image
- %type_sampler = OpTypeSampler
- %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
- %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
- %_ptr_int = OpTypePointer Function %int
- %v2int = OpTypeVector %int 2
- %10 = OpTypeVector %float 4
- %void = OpTypeVoid
- %22 = OpTypeFunction %void
- %v2float = OpTypeVector %float 2
- %v3int = OpTypeVector %int 3
- %Texture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
- %gSampler = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
- %110 = OpConstantComposite %v2int %5 %5
- %101 = OpConstantComposite %v2int %int_n1 %int_n1
- %20 = OpConstantComposite %v2float %float_0 %float_0
- %main = OpFunction %void None %22
- %23 = OpLabel
- %var = OpVariable %_ptr_int Function
- %88 = OpLoad %type_2d_image %Texture
- %val = OpLoad %int %var
- %sampler = OpLoad %type_sampler %gSampler
- %26 = OpSampledImage %type_sampled_image %88 %sampler
- )" + image_instruction + R"(
- OpReturn
- OpFunctionEnd
- )";
- return body;
- }
- INSTANTIATE_TEST_SUITE_P(ImageOperandsBitmaskFoldingTest, MatchingInstructionWithNoResultFoldingTest,
- ::testing::Values(
- // Test case 0: OpImageFetch without Offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- "%89 = OpImageFetch %10 %88 %101 Lod %5 \n")
- , 89, false),
- // Test case 1: OpImageFetch with non-const offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- "%89 = OpImageFetch %10 %88 %101 Lod|Offset %5 %val \n")
- , 89, false),
- // Test case 2: OpImageFetch with Lod and Offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " %89 = OpImageFetch %10 %88 %101 Lod|Offset %5 %101 \n"
- "; CHECK: %89 = OpImageFetch %10 %88 %101 Lod|ConstOffset %5 %101 \n")
- , 89, true),
- // Test case 3: OpImageFetch with Bias and Offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " %89 = OpImageFetch %10 %88 %101 Bias|Offset %5 %101 \n"
- "; CHECK: %89 = OpImageFetch %10 %88 %101 Bias|ConstOffset %5 %101 \n")
- , 89, true),
- // Test case 4: OpImageFetch with Grad and Offset.
- // Grad adds 2 operands to the instruction.
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " %89 = OpImageFetch %10 %88 %101 Grad|Offset %5 %5 %101 \n"
- "; CHECK: %89 = OpImageFetch %10 %88 %101 Grad|ConstOffset %5 %5 %101 \n")
- , 89, true),
- // Test case 5: OpImageFetch with Offset and MinLod.
- // This is an example of a case where the bitmask bit-offset is larger than
- // that of the Offset.
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " %89 = OpImageFetch %10 %88 %101 Offset|MinLod %101 %5 \n"
- "; CHECK: %89 = OpImageFetch %10 %88 %101 ConstOffset|MinLod %101 %5 \n")
- , 89, true),
- // Test case 6: OpImageGather with constant Offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " %89 = OpImageGather %10 %26 %20 %5 Offset %101 \n"
- "; CHECK: %89 = OpImageGather %10 %26 %20 %5 ConstOffset %101 \n")
- , 89, true),
- // Test case 7: OpImageWrite with constant Offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " OpImageWrite %88 %5 %101 Offset %101 \n"
- "; CHECK: OpImageWrite %88 %5 %101 ConstOffset %101 \n")
- , 0 /* No result-id */, true),
- // Test case 8: OpImageFetch with zero constant Offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " %89 = OpImageFetch %10 %88 %101 Lod|Offset %5 %110 \n"
- "; CHECK: %89 = OpImageFetch %10 %88 %101 Lod %5 \n")
- , 89, true)
- ));
- } // namespace
- } // namespace opt
- } // namespace spvtools
|