1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199 |
- // 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 <limits>
- #include <memory>
- #include <string>
- #include <unordered_set>
- #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/fold.h"
- #include "source/opt/ir_context.h"
- #include "source/opt/module.h"
- #include "spirv-tools/libspirv.hpp"
- #include "test/opt/pass_utils.h"
- 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;
- };
- using IntegerInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<uint32_t>>;
- TEST_P(IntegerInstructionFoldingTest, 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);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- // Make sure the instruction folded as expected.
- EXPECT_TRUE(succeeded);
- if (inst != nullptr) {
- EXPECT_EQ(inst->opcode(), SpvOpCopyObject);
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- EXPECT_EQ(inst->opcode(), SpvOpConstant);
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::IntConstant* result =
- const_mrg->GetConstantFromInst(inst)->AsIntConstant();
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- EXPECT_EQ(result->GetU32BitValue(), tc.expected_result);
- }
- }
- }
- // 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
- const std::string& Header() {
- static const std::string header = R"(OpCapability Shader
- OpCapability Float16
- OpCapability Float64
- OpCapability Int16
- OpCapability Int64
- %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
- %int = OpTypeInt 32 1
- %long = OpTypeInt 64 1
- %uint = OpTypeInt 32 0
- %v2int = OpTypeVector %int 2
- %v4int = OpTypeVector %int 4
- %v4float = OpTypeVector %float 4
- %v4double = OpTypeVector %double 4
- %v2float = OpTypeVector %float 2
- %v2double = OpTypeVector %double 2
- %v2bool = OpTypeVector %bool 2
- %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_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
- %short_0 = OpConstant %short 0
- %short_2 = OpConstant %short 2
- %short_3 = OpConstant %short 3
- %100 = OpConstant %int 0 ; 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_2 = OpConstant %int 2
- %int_3 = OpConstant %int 3
- %int_4 = OpConstant %int 4
- %int_n24 = OpConstant %int -24
- %int_min = OpConstant %int -2147483648
- %int_max = OpConstant %int 2147483647
- %long_0 = OpConstant %long 0
- %long_2 = OpConstant %long 2
- %long_3 = OpConstant %long 3
- %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_max = OpConstant %uint 4294967295
- %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_4_4 = OpConstantComposite %v2int %int_4 %int_4
- %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_0_0_0_0 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
- %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_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %float_3 = OpConstant %float 3
- %float_4 = OpConstant %float 4
- %float_0p5 = OpConstant %float 0.5
- %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_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_1 = OpConstant %double 1
- %double_2 = OpConstant %double 2
- %double_3 = OpConstant %double 3
- %double_4 = OpConstant %double 4
- %double_0p5 = OpConstant %double 0.5
- %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
- %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
- %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_1_1_0p5 = OpConstantComposite %v4double %double_1 %double_1 %double_1 %double_0p5
- %v4double_null = OpConstantNull %v4double
- %v4float_n1_2_1_3 = OpConstantComposite %v4float %float_n1 %float_2 %float_1 %float_3
- )";
- 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())
- ));
- // clang-format on
- using IntVectorInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<std::vector<uint32_t>>>;
- TEST_P(IntVectorInstructionFoldingTest, 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);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- SpvOp original_opcode = inst->opcode();
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- // Make sure the instruction folded as expected.
- EXPECT_EQ(succeeded, inst == nullptr || inst->opcode() != original_opcode);
- if (succeeded && inst != nullptr) {
- EXPECT_EQ(inst->opcode(), SpvOpCopyObject);
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- std::vector<SpvOp> opcodes = {SpvOpConstantComposite};
- 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(), tc.expected_result.size());
- for (size_t i = 0; i < componenets.size(); i++) {
- EXPECT_EQ(tc.expected_result[i], componenets[i]->GetU32());
- }
- }
- }
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(TestCase, IntVectorInstructionFoldingTest,
- ::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}),
- 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 4294967295 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {0,0}),
- 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 4294967295 \n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {0,0})
- ));
- // clang-format on
- using BooleanInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<bool>>;
- TEST_P(BooleanInstructionFoldingTest, 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);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- // Make sure the instruction folded as expected.
- EXPECT_TRUE(succeeded);
- if (inst != nullptr) {
- EXPECT_EQ(inst->opcode(), SpvOpCopyObject);
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- std::vector<SpvOp> bool_opcodes = {SpvOpConstantTrue, SpvOpConstantFalse};
- EXPECT_THAT(bool_opcodes, Contains(inst->opcode()));
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::BoolConstant* result =
- const_mrg->GetConstantFromInst(inst)->AsBoolConstant();
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- EXPECT_EQ(result->value(), tc.expected_result);
- }
- }
- }
- // 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();
- // 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);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- // Make sure the instruction folded as expected.
- EXPECT_TRUE(succeeded);
- if (inst != nullptr) {
- EXPECT_EQ(inst->opcode(), SpvOpCopyObject);
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- EXPECT_EQ(inst->opcode(), SpvOpConstant);
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::FloatConstant* result =
- const_mrg->GetConstantFromInst(inst)->AsFloatConstant();
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- EXPECT_EQ(result->GetFloatValue(), tc.expected_result);
- }
- }
- }
- // 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)
- ));
- // clang-format on
- using DoubleInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<double>>;
- TEST_P(DoubleInstructionFoldingTest, 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);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- // Make sure the instruction folded as expected.
- EXPECT_TRUE(succeeded);
- if (inst != nullptr) {
- EXPECT_EQ(inst->opcode(), SpvOpCopyObject);
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- EXPECT_EQ(inst->opcode(), SpvOpConstant);
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::FloatConstant* result =
- const_mrg->GetConstantFromInst(inst)->AsFloatConstant();
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- EXPECT_EQ(result->GetDoubleValue(), tc.expected_result);
- }
- }
- }
- // 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)
- ));
- // 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();
- // 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);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- inst = context->get_instruction_folder().FoldInstructionToConstant(inst,
- tc.id_map);
- // Make sure the instruction folded as expected.
- EXPECT_NE(inst, nullptr);
- if (inst != nullptr) {
- EXPECT_EQ(inst->opcode(), SpvOpConstant);
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::IntConstant* result =
- const_mrg->GetConstantFromInst(inst)->AsIntConstant();
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- EXPECT_EQ(result->GetU32BitValue(), tc.expected_result);
- }
- }
- }
- // 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();
- // 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);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- inst = context->get_instruction_folder().FoldInstructionToConstant(inst,
- tc.id_map);
- // Make sure the instruction folded as expected.
- EXPECT_NE(inst, nullptr);
- if (inst != nullptr) {
- std::vector<SpvOp> bool_opcodes = {SpvOpConstantTrue, SpvOpConstantFalse};
- EXPECT_THAT(bool_opcodes, Contains(inst->opcode()));
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::BoolConstant* result =
- const_mrg->GetConstantFromInst(inst)->AsBoolConstant();
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- EXPECT_EQ(result->value(), tc.expected_result);
- }
- }
- }
- // 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();
- // 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);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- // Make sure the instruction folded as expected.
- EXPECT_EQ(inst->result_id(), original_inst->result_id());
- EXPECT_EQ(inst->type_id(), original_inst->type_id());
- EXPECT_TRUE((!succeeded) == (tc.expected_result == 0));
- if (succeeded) {
- EXPECT_EQ(inst->opcode(), SpvOpCopyObject);
- EXPECT_EQ(inst->GetSingleWordInOperand(0), tc.expected_result);
- } else {
- 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));
- }
- }
- }
- // 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: Don't fold 2 + 3 (long), bad length
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpIAdd %long %long_2 %long_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 39: Don't fold 2 + 3 (short), bad length
- 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, 0),
- // Test case 40: 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 41: 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)
- ));
- 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)
- ));
- 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)
- ));
- 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 * 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 10: 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 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 = OpFDiv %float %104 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, FLOAT_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_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 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_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 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_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 15: 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 16: 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 15: 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 16: 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 17: 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 18: 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)
- ));
- 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(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 = OpIAdd %uint %3 %uint_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 3: 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 4: 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 5: 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 6: 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 7: 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)
- ));
- 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();
- // 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);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- // Make sure the instruction folded as expected.
- EXPECT_EQ(inst->result_id(), original_inst->result_id());
- EXPECT_EQ(inst->type_id(), original_inst->type_id());
- EXPECT_TRUE((!succeeded) == (tc.expected_result == 0));
- if (succeeded) {
- EXPECT_EQ(inst->opcode(), SpvOpFNegate);
- EXPECT_EQ(inst->GetSingleWordInOperand(0), tc.expected_result);
- } else {
- 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));
- }
- }
- }
- // 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();
- // 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);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_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(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\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\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\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\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\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\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\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\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\n" +
- "; CHECK: [[float_n1:%\\w+]] = OpConstant [[float]] -1\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2\n" +
- "; CHECK: [[float_n3:%\\w+]] = OpConstant [[float]] -3\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)
- ));
- 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\n" +
- "; CHECK: OpConstant [[int]] -2147483648\n" +
- "; CHECK: [[int_n2:%\\w+]] = OpConstant [[int]] -2\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\n" +
- "; CHECK: OpConstant [[int]] -2147483648\n" +
- "; CHECK: [[int_n2:%\\w+]] = OpConstant [[int]] -2\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)
- ));
- 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: merge sdiv of snegate
- // (-x) / 2 = x / -2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: OpConstant [[int]] -2147483648\n" +
- "; CHECK: [[int_n2:%\\w+]] = OpConstant [[int]] -2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpSDiv [[int]] [[ld]] [[int_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 = OpSNegate %int %2\n" +
- "%4 = OpSDiv %int %3 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 12: merge sdiv of snegate
- // 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\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpSDiv [[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 = OpSNegate %int %2\n" +
- "%4 = OpSDiv %int %int_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // 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)
- ));
- 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)
- ));
- 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\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\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)
- ));
- 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(CompositeExtractMatchingTest, 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)
- ));
- 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)
- ));
- 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 guarentee which one is used.
- TEST_P(MatchingInstructionWithNoResultFoldingTest, 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);
- // Fold the instruction to test.
- Instruction* inst = nullptr;
- Function* func = &*context->module()->begin();
- for (auto& bb : *func) {
- Instruction* terminator = bb.terminator();
- if (terminator->IsReturnOrAbort()) {
- inst = terminator->PreviousNode();
- break;
- }
- }
- assert(inst && "Invalid test. Could not find 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(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)
- ));
- } // namespace
- } // namespace opt
- } // namespace spvtools
|