| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322 |
- // Copyright (c) 2016 Google Inc.
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include "source/opt/fold.h"
- #include <limits>
- #include <memory>
- #include <string>
- #include <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/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
- %v2half = OpTypeVector %half 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_2049 = OpConstant %float 2049
- %float_n2049 = OpConstant %float -2049
- %float_0p5 = OpConstant %float 0.5
- %float_0p2 = OpConstant %float 0.2
- %float_pi = OpConstant %float 1.5555
- %float_1e16 = OpConstant %float 1e16
- %float_n1e16 = OpConstant %float -1e16
- %float_1en16 = OpConstant %float 1e-16
- %float_n1en16 = OpConstant %float -1e-16
- %v2float_0_0 = OpConstantComposite %v2float %float_0 %float_0
- %v2float_2_2 = OpConstantComposite %v2float %float_2 %float_2
- %v2float_2_3 = OpConstantComposite %v2float %float_2 %float_3
- %v2float_3_2 = OpConstantComposite %v2float %float_3 %float_2
- %v2float_4_4 = OpConstantComposite %v2float %float_4 %float_4
- %v2float_2_0p5 = OpConstantComposite %v2float %float_2 %float_0p5
- %v2float_0p2_0p5 = OpConstantComposite %v2float %float_0p2 %float_0p5
- %v2float_null = OpConstantNull %v2float
- %double_n1 = OpConstant %double -1
- %105 = OpConstant %double 0 ; Need a def with an numerical id to define id maps.
- %double_null = OpConstantNull %double
- %double_0 = OpConstant %double 0
- %double_1 = OpConstant %double 1
- %double_2 = OpConstant %double 2
- %double_3 = OpConstant %double 3
- %double_4 = OpConstant %double 4
- %double_5 = OpConstant %double 5
- %double_0p5 = OpConstant %double 0.5
- %double_0p2 = OpConstant %double 0.2
- %v2double_0_0 = OpConstantComposite %v2double %double_0 %double_0
- %v2double_2_2 = OpConstantComposite %v2double %double_2 %double_2
- %v2double_2_3 = OpConstantComposite %v2double %double_2 %double_3
- %v2double_3_2 = OpConstantComposite %v2double %double_3 %double_2
- %v2double_4_4 = OpConstantComposite %v2double %double_4 %double_4
- %v2double_2_0p5 = OpConstantComposite %v2double %double_2 %double_0p5
- %v2double_null = OpConstantNull %v2double
- %108 = OpConstant %half 0
- %half_1 = OpConstant %half 1
- %half_0_1 = OpConstantComposite %v2half %108 %half_1
- %106 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %v4float_0_0_0_0 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
- %v4float_0_0_0_1 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
- %v4float_0_1_0_0 = OpConstantComposite %v4float %float_0 %float_1 %float_null %float_0
- %v4float_1_1_1_1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
- %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()),
- // Test case 30: fold UMin 3 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UMin %uint_3 %uint_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 31: fold UMin 4 2
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UMin %uint_4 %uint_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2),
- // Test case 32: fold SMin 3 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 UMin %int_3 %int_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 33: fold SMin 4 2
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 SMin %int_4 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2),
- // Test case 34: fold UMax 3 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UMax %uint_3 %uint_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4),
- // Test case 35: fold UMax 3 2
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UMax %uint_3 %uint_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 36: fold SMax 3 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 UMax %int_3 %int_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4),
- // Test case 37: fold SMax 3 2
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 SMax %int_3 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 38: fold UClamp 2 3 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UClamp %uint_2 %uint_3 %uint_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 39: fold UClamp 2 0 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UClamp %uint_2 %uint_0 %uint_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2),
- // Test case 40: fold UClamp 2 0 1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %uint %1 UClamp %uint_2 %uint_0 %uint_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1),
- // Test case 41: fold SClamp 2 3 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 SClamp %int_2 %int_3 %int_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 42: fold SClamp 2 0 4
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 SClamp %int_2 %int_0 %int_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2),
- // Test case 43: fold SClamp 2 0 1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %int %1 SClamp %int_2 %int_0 %int_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1),
- // Test case 44: SClamp 1 2 x
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %int\n" +
- "%2 = OpExtInst %int %1 SClamp %int_1 %int_2 %undef\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2),
- // Test case 45: SClamp 2 x 1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %int\n" +
- "%2 = OpExtInst %int %1 SClamp %int_2 %undef %int_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1),
- // Test case 44: UClamp 1 2 x
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %uint\n" +
- "%2 = OpExtInst %uint %1 UClamp %uint_1 %uint_2 %undef\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2),
- // Test case 45: UClamp 2 x 1
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %uint\n" +
- "%2 = OpExtInst %uint %1 UClamp %uint_2 %undef %uint_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1)
- ));
- // 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 FloatVectorInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<std::vector<float>>>;
- TEST_P(FloatVectorInstructionFoldingTest, 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]->GetFloat());
- }
- }
- }
- }
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(TestCase, FloatVectorInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: FMix {2.0, 2.0}, {2.0, 3.0} {0.2,0.5}
- InstructionFoldingCase<std::vector<float>>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %v2float %1 FMix %v2float_2_3 %v2float_0_0 %v2float_0p2_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, {1.6f,1.5f})
- ));
- // 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) {
- if (!std::isnan(tc.expected_result)) {
- EXPECT_EQ(result->GetFloatValue(), tc.expected_result);
- } else {
- EXPECT_TRUE(std::isnan(result->GetFloatValue()));
- }
- }
- }
- }
- // Not testing NaNs because there are no expectations concerning NaNs according
- // to the "Precision and Operation of SPIR-V Instructions" section of the Vulkan
- // specification.
- // clang-format off
- INSTANTIATE_TEST_SUITE_P(FloatConstantFoldingTest, FloatInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Fold 2.0 - 1.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFSub %float %float_2 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 1: Fold 2.0 + 1.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFAdd %float %float_2 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3.0),
- // Test case 2: Fold 3.0 * 2.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFMul %float %float_3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 6.0),
- // Test case 3: Fold 1.0 / 2.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %float %float_1 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.5),
- // Test case 4: Fold 1.0 / 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %float %float_1 %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<float>::infinity()),
- // Test case 5: Fold -1.0 / 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFDiv %float %float_n1 %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -std::numeric_limits<float>::infinity()),
- // Test case 6: Fold (2.0, 3.0) dot (2.0, 0.5)
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpDot %float %v2float_2_3 %v2float_2_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 5.5f),
- // Test case 7: Fold (0.0, 0.0) dot v
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%v = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %v\n" +
- "%3 = OpDot %float %v2float_0_0 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0.0f),
- // Test case 8: Fold v dot (0.0, 0.0)
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%v = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %v\n" +
- "%3 = OpDot %float %2 %v2float_0_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0.0f),
- // Test case 9: Fold Null dot v
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%v = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %v\n" +
- "%3 = OpDot %float %v2float_null %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0.0f),
- // Test case 10: Fold v dot Null
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%v = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %v\n" +
- "%3 = OpDot %float %2 %v2float_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0.0f),
- // Test case 11: Fold -2.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFNegate %float %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -2),
- // Test case 12: QuantizeToF16 1.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 13: QuantizeToF16 positive non exact
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_2049\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2048),
- // Test case 14: QuantizeToF16 negative non exact
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_n2049\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -2048),
- // Test case 15: QuantizeToF16 large positive
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_1e16\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<float>::infinity()),
- // Test case 16: QuantizeToF16 large negative
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_n1e16\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, -std::numeric_limits<float>::infinity()),
- // Test case 17: QuantizeToF16 small positive
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_1en16\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 18: QuantizeToF16 small negative
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_n1en16\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 19: QuantizeToF16 nan
- InstructionFoldingCase<float>(
- HeaderWithNaN() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpQuantizeToF16 %float %float_nan\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, std::numeric_limits<float>::quiet_NaN()),
- // Test case 20: FMix 1.0 4.0 0.2
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FMix %float_1 %float_4 %float_0p2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.6f),
- // Test case 21: FMin 1.0 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FMin %float_1 %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0f),
- // Test case 22: FMin 4.0 0.2
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FMin %float_4 %float_0p2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.2f),
- // Test case 23: FMax 1.0 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FMax %float_1 %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4.0f),
- // Test case 24: FMax 1.0 0.2
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FMax %float_1 %float_0p2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0f),
- // Test case 25: FClamp 1.0 0.2 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FClamp %float_1 %float_0p2 %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0f),
- // Test case 26: FClamp 0.2 2.0 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FClamp %float_0p2 %float_2 %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0f),
- // Test case 27: FClamp 2049.0 2.0 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 FClamp %float_2049 %float_2 %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4.0f),
- // Test case 28: FClamp 1.0 2.0 x
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %float\n" +
- "%2 = OpExtInst %float %1 FClamp %float_1 %float_2 %undef\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0),
- // Test case 29: FClamp 1.0 x 0.5
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %float\n" +
- "%2 = OpExtInst %float %1 FClamp %float_1 %undef %float_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.5),
- // Test case 30: Sin 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Sin %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 31: Cos 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Cos %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 32: Tan 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Tan %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 33: Asin 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Asin %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 34: Acos 1.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Acos %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 35: Atan 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Atan %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 36: Exp 0.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Exp %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 37: Log 1.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Log %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 38: Exp2 2.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Exp2 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4.0),
- // Test case 39: Log2 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Log2 %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0),
- // Test case 40: Sqrt 4.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Sqrt %float_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0),
- // Test case 41: Atan2 0.0 1.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Atan2 %float_0 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.0),
- // Test case 42: Pow 2.0 3.0
- InstructionFoldingCase<float>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %float %1 Pow %float_2 %float_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 8.0)
- ));
- // 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),
- // Test case 12: FMin 1.0 4.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FMin %double_1 %double_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 13: FMin 4.0 0.2
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FMin %double_4 %double_0p2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.2),
- // Test case 14: FMax 1.0 4.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FMax %double_1 %double_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4.0),
- // Test case 15: FMax 1.0 0.2
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FMax %double_1 %double_0p2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 16: FClamp 1.0 0.2 4.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FClamp %double_1 %double_0p2 %double_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 1.0),
- // Test case 17: FClamp 0.2 2.0 4.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FClamp %double_0p2 %double_2 %double_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0),
- // Test case 18: FClamp 5.0 2.0 4.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpExtInst %double %1 FClamp %double_5 %double_2 %double_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 4.0),
- // Test case 19: FClamp 1.0 2.0 x
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %double\n" +
- "%2 = OpExtInst %double %1 FClamp %double_1 %double_2 %undef\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0),
- // Test case 20: FClamp 1.0 x 0.5
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %double\n" +
- "%2 = OpExtInst %double %1 FClamp %double_1 %undef %double_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0.5),
- // Test case 21: Sqrt 4.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %double\n" +
- "%2 = OpExtInst %double %1 Sqrt %double_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 2.0),
- // Test case 22: Pow 2.0 3.0
- InstructionFoldingCase<double>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%undef = OpUndef %double\n" +
- "%2 = OpExtInst %double %1 Pow %double_2 %double_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 8.0)
- ));
- // 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),
- // Test case 42: Don't fold comparisons of 64-bit types
- // (https://github.com/KhronosGroup/SPIRV-Tools/issues/3343).
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpSLessThan %bool %long_0 %long_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0)
- ));
- INSTANTIATE_TEST_SUITE_P(CompositeExtractFoldingTest, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold Insert feeding extract
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeInsert %v4int %2 %v4int_0_0_0_0 0\n" +
- "%4 = OpCompositeInsert %v4int %int_1 %3 1\n" +
- "%5 = OpCompositeInsert %v4int %int_1 %4 2\n" +
- "%6 = OpCompositeInsert %v4int %int_1 %5 3\n" +
- "%7 = OpCompositeExtract %int %6 0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 7, 2),
- // Test case 1: fold Composite construct feeding extract (position 0)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeConstruct %v4int %2 %int_0 %int_0 %int_0\n" +
- "%4 = OpCompositeExtract %int %3 0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, 2),
- // Test case 2: fold Composite construct feeding extract (position 3)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeConstruct %v4int %2 %int_0 %int_0 %100\n" +
- "%4 = OpCompositeExtract %int %3 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, INT_0_ID),
- // Test case 3: fold Composite construct with vectors feeding extract (scalar element)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeConstruct %v2int %2 %int_0\n" +
- "%4 = OpCompositeConstruct %v4int %3 %int_0 %100\n" +
- "%5 = OpCompositeExtract %int %4 3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, INT_0_ID),
- // Test case 4: fold Composite construct with vectors feeding extract (start of vector element)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeConstruct %v2int %2 %int_0\n" +
- "%4 = OpCompositeConstruct %v4int %3 %int_0 %100\n" +
- "%5 = OpCompositeExtract %int %4 0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, 2),
- // Test case 5: fold Composite construct with vectors feeding extract (middle of vector element)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeConstruct %v2int %int_0 %2\n" +
- "%4 = OpCompositeConstruct %v4int %3 %int_0 %100\n" +
- "%5 = OpCompositeExtract %int %4 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, 2),
- // Test case 6: fold Composite construct with multiple indices.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %n\n" +
- "%3 = OpCompositeConstruct %v2int %int_0 %2\n" +
- "%4 = OpCompositeConstruct %struct_v2int_int_int %3 %int_0 %100\n" +
- "%5 = OpCompositeExtract %int %4 0 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 5, 2),
- // Test case 7: fold constant extract.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeExtract %int %102 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, INT_7_ID),
- // Test case 8: constant struct has OpUndef
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeExtract %int %struct_undef_0_0 0 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 9: Extracting a member of element inserted via Insert
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_struct_v2int_int_int Function\n" +
- "%2 = OpLoad %struct_v2int_int_int %n\n" +
- "%3 = OpCompositeInsert %struct_v2int_int_int %102 %2 0\n" +
- "%4 = OpCompositeExtract %int %3 0 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, 103),
- // Test case 10: Extracting a element that is partially changed by Insert. (Don't fold)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_struct_v2int_int_int Function\n" +
- "%2 = OpLoad %struct_v2int_int_int %n\n" +
- "%3 = OpCompositeInsert %struct_v2int_int_int %int_0 %2 0 1\n" +
- "%4 = OpCompositeExtract %v2int %3 0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, 0),
- // Test case 11: Extracting from result of vector shuffle (first input)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%2 = OpLoad %v2int %n\n" +
- "%3 = OpVectorShuffle %v2int %102 %2 3 0\n" +
- "%4 = OpCompositeExtract %int %3 1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, INT_7_ID),
- // Test case 12: Extracting from result of vector shuffle (second input)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2int Function\n" +
- "%2 = OpLoad %v2int %n\n" +
- "%3 = OpVectorShuffle %v2int %2 %102 2 0\n" +
- "%4 = OpCompositeExtract %int %3 0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, INT_7_ID),
- // Test case 13: https://github.com/KhronosGroup/SPIRV-Tools/issues/2608
- // Out of bounds access. Do not fold.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1\n" +
- "%3 = OpCompositeExtract %float %2 4\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 3, 0),
- // Test case 14: https://github.com/KhronosGroup/SPIRV-Tools/issues/3631
- // Extract the component right after the vector constituent.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeConstruct %v2int %int_0 %int_0\n" +
- "%3 = OpCompositeConstruct %v4int %2 %100 %int_0\n" +
- "%4 = OpCompositeExtract %int %3 2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, INT_0_ID)
- ));
- INSTANTIATE_TEST_SUITE_P(CompositeConstructFoldingTest, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold Extracts feeding construct
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCopyObject %v4int %v4int_0_0_0_0\n" +
- "%3 = OpCompositeExtract %int %2 0\n" +
- "%4 = OpCompositeExtract %int %2 1\n" +
- "%5 = OpCompositeExtract %int %2 2\n" +
- "%6 = OpCompositeExtract %int %2 3\n" +
- "%7 = OpCompositeConstruct %v4int %3 %4 %5 %6\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 7, 2),
- // Test case 1: Don't fold Extracts feeding construct (Different source)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCopyObject %v4int %v4int_0_0_0_0\n" +
- "%3 = OpCompositeExtract %int %2 0\n" +
- "%4 = OpCompositeExtract %int %2 1\n" +
- "%5 = OpCompositeExtract %int %2 2\n" +
- "%6 = OpCompositeExtract %int %v4int_0_0_0_0 3\n" +
- "%7 = OpCompositeConstruct %v4int %3 %4 %5 %6\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 7, 0),
- // Test case 2: Don't fold Extracts feeding construct (bad indices)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCopyObject %v4int %v4int_0_0_0_0\n" +
- "%3 = OpCompositeExtract %int %2 0\n" +
- "%4 = OpCompositeExtract %int %2 0\n" +
- "%5 = OpCompositeExtract %int %2 2\n" +
- "%6 = OpCompositeExtract %int %2 3\n" +
- "%7 = OpCompositeConstruct %v4int %3 %4 %5 %6\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 7, 0),
- // Test case 3: Don't fold Extracts feeding construct (different type)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCopyObject %struct_v2int_int_int %struct_v2int_int_int_null\n" +
- "%3 = OpCompositeExtract %v2int %2 0\n" +
- "%4 = OpCompositeExtract %int %2 1\n" +
- "%5 = OpCompositeExtract %int %2 2\n" +
- "%7 = OpCompositeConstruct %v4int %3 %4 %5\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 7, 0),
- // Test case 4: Fold construct with constants to constant.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpCompositeConstruct %v2int %103 %103\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, VEC2_0_ID),
- // Test case 5: Don't segfault when trying to fold an OpCompositeConstruct
- // for an empty struct, and we reached the id limit.
- InstructionFoldingCase<uint32_t>(
- Header() + "%empty_struct = OpTypeStruct\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%4194303 = OpCompositeConstruct %empty_struct\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4194303, 0)
- ));
- INSTANTIATE_TEST_SUITE_P(PhiFoldingTest, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Fold phi with the same values for all edges.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- " OpBranchConditional %true %l1 %l2\n" +
- "%l1 = OpLabel\n" +
- " OpBranch %merge_lab\n" +
- "%l2 = OpLabel\n" +
- " OpBranch %merge_lab\n" +
- "%merge_lab = OpLabel\n" +
- "%2 = OpPhi %int %100 %l1 %100 %l2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, INT_0_ID),
- // Test case 1: Fold phi in pass through loop.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- " OpBranch %l1\n" +
- "%l1 = OpLabel\n" +
- "%2 = OpPhi %int %100 %main_lab %2 %l1\n" +
- " OpBranchConditional %true %l1 %merge_lab\n" +
- "%merge_lab = OpLabel\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, INT_0_ID),
- // Test case 2: Don't Fold phi because of different values.
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- " OpBranch %l1\n" +
- "%l1 = OpLabel\n" +
- "%2 = OpPhi %int %int_0 %main_lab %int_3 %l1\n" +
- " OpBranchConditional %true %l1 %merge_lab\n" +
- "%merge_lab = OpLabel\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0)
- ));
- INSTANTIATE_TEST_SUITE_P(FloatRedundantFoldingTest, GeneralInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: Don't fold n + 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFAdd %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 1: Don't fold n - 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFSub %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 2: Don't fold n * 2.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFMul %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 3: Fold n + 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFAdd %float %3 %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 4: Fold 0.0 + n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFAdd %float %float_0 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 5: Fold n - 0.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFSub %float %3 %float_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 6: Fold n * 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFMul %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 7: Fold 1.0 * n
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFMul %float %float_1 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 8: Fold n / 1.0
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %n\n" +
- "%2 = OpFDiv %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 3),
- // Test case 9: Fold n * 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 17: 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 18: 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 19: 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 20: Don't fold 1.0 * 1.0 (half)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFMul %half %half_1 %half_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 21: Don't fold (0.0, 1.0) * (0.0, 1.0) (half)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFMul %v2half %half_0_1 %half_0_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 22: Don't fold (0.0, 1.0) dotp (0.0, 1.0) (half)
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpDot %half %half_0_1 %half_0_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0)
- ));
- 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{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[ld]] [[float_n2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFMul %float %2 %float_2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 2: fold fnegate(fmul with const).
- // -(2.0 * x) = x * 2.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[ld]] [[float_n2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFMul %float %float_2 %2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 3: fold fnegate(fdiv with const).
- // -(x / 2.0) = x * -0.5
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n0p5:%\\w+]] = OpConstant [[float]] -0.5\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[ld]] [[float_n0p5]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %2 %float_2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 4: fold fnegate(fdiv with const).
- // -(2.0 / x) = -2.0 / x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFDiv [[float]] [[float_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %float_2 %2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 5: fold fnegate(fadd with const).
- // -(2.0 + x) = -2.0 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %float_2 %2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 6: fold fnegate(fadd with const).
- // -(x + 2.0) = -2.0 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %2 %float_2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 7: fold fnegate(fsub with const).
- // -(2.0 - x) = x - 2.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[ld]] [[float_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %float_2 %2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 8: fold fnegate(fsub with const).
- // -(x - 2.0) = 2.0 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %2 %float_2\n" +
- "%4 = OpFNegate %float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 9: fold consecutive snegate
- // -(-x) = x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int:%\\w+]]\n" +
- "; CHECK: %4 = OpCopyObject [[int]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSNegate %int %2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 10: fold consecutive vector negate
- // -(-x) = x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2float:%\\w+]]\n" +
- "; CHECK: %4 = OpCopyObject [[v2float]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %var\n" +
- "%3 = OpFNegate %v2float %2\n" +
- "%4 = OpFNegate %v2float %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 11: fold snegate(iadd with const).
- // -(2 + x) = -2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: OpConstant [[int]] -2147483648\n" +
- "; CHECK: [[int_n2:%\\w+]] = OpConstant [[int]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpISub [[int]] [[int_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIAdd %int %int_2 %2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 12: fold snegate(iadd with const).
- // -(x + 2) = -2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: OpConstant [[int]] -2147483648\n" +
- "; CHECK: [[int_n2:%\\w+]] = OpConstant [[int]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpISub [[int]] [[int_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIAdd %int %2 %int_2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 13: fold snegate(isub with const).
- // -(2 - x) = x - 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpISub [[int]] [[ld]] [[int_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpISub %int %int_2 %2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 14: fold snegate(isub with const).
- // -(x - 2) = 2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int_2:%\\w+]] = OpConstant [[int]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpISub [[int]] [[int_2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpISub %int %2 %int_2\n" +
- "%4 = OpSNegate %int %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 15: fold snegate(iadd with const).
- // -(x + 2) = -2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_n2:%\\w+]] = OpConstant [[long]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpISub [[long]] [[long_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpIAdd %long %2 %long_2\n" +
- "%4 = OpSNegate %long %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 16: fold snegate(isub with const).
- // -(2 - x) = x - 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_2:%\\w+]] = OpConstant [[long]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpISub [[long]] [[ld]] [[long_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpISub %long %long_2 %2\n" +
- "%4 = OpSNegate %long %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 17: fold snegate(isub with const).
- // -(x - 2) = 2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_2:%\\w+]] = OpConstant [[long]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpISub [[long]] [[long_2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpISub %long %2 %long_2\n" +
- "%4 = OpSNegate %long %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 4, true),
- // Test case 18: fold -vec4(-1.0, 2.0, 1.0, 3.0)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[v4float:%\\w+]] = OpTypeVector [[float]] 4{{[[:space:]]}}\n" +
- "; CHECK: [[float_n1:%\\w+]] = OpConstant [[float]] -1{{[[:space:]]}}\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1{{[[:space:]]}}\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[float_n3:%\\w+]] = OpConstant [[float]] -3{{[[:space:]]}}\n" +
- "; CHECK: [[v4float_1_n2_n1_n3:%\\w+]] = OpConstantComposite [[v4float]] [[float_1]] [[float_n2]] [[float_n1]] [[float_n3]]\n" +
- "; CHECK: %2 = OpCopyObject [[v4float]] [[v4float_1_n2_n1_n3]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFNegate %v4float %v4float_n1_2_1_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 19: fold vector fnegate with null
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v2double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: [[double_n0:%\\w+]] = OpConstant [[double]] -0\n" +
- "; CHECK: [[v2double_0_0:%\\w+]] = OpConstantComposite [[v2double]] [[double_n0]] [[double_n0]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2double]] [[v2double_0_0]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpFNegate %v2double %v2double_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true)
- ));
- INSTANTIATE_TEST_SUITE_P(ReciprocalFDivTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: scalar reicprocal
- // x / 0.5 = x * 2.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %3 = OpFMul [[float]] [[ld]] [[float_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %2 %float_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 3, true),
- // Test case 1: Unfoldable
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_0:%\\w+]] = OpConstant [[float]] 0\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %3 = OpFDiv [[float]] [[ld]] [[float_0]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %2 %104\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 3, false),
- // Test case 2: Vector reciprocal
- // x / {2.0, 0.5} = x * {0.5, 2.0}
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[v2float:%\\w+]] = OpTypeVector [[float]] 2\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[float_0p5:%\\w+]] = OpConstant [[float]] 0.5\n" +
- "; CHECK: [[v2float_0p5_2:%\\w+]] = OpConstantComposite [[v2float]] [[float_0p5]] [[float_2]]\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2float]]\n" +
- "; CHECK: %3 = OpFMul [[v2float]] [[ld]] [[v2float_0p5_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %var\n" +
- "%3 = OpFDiv %v2float %2 %v2float_2_0p5\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 3, true),
- // Test case 3: double reciprocal
- // x / 2.0 = x * 0.5
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[double_0p5:%\\w+]] = OpConstant [[double]] 0.5\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[double]]\n" +
- "; CHECK: %3 = OpFMul [[double]] [[ld]] [[double_0p5]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_double Function\n" +
- "%2 = OpLoad %double %var\n" +
- "%3 = OpFDiv %double %2 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 3, true),
- // Test case 4: don't fold x / 0.
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %var\n" +
- "%3 = OpFDiv %v2float %2 %v2float_null\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 3, false)
- ));
- INSTANTIATE_TEST_SUITE_P(MergeMulTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: fold consecutive fmuls
- // (x * 3.0) * 2.0 = x * 6.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_6:%\\w+]] = OpConstant [[float]] 6\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[ld]] [[float_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFMul %float %2 %float_3\n" +
- "%4 = OpFMul %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 1: fold consecutive fmuls
- // 2.0 * (x * 3.0) = x * 6.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_6:%\\w+]] = OpConstant [[float]] 6\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[ld]] [[float_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFMul %float %2 %float_3\n" +
- "%4 = OpFMul %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 2: fold consecutive fmuls
- // (3.0 * x) * 2.0 = x * 6.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_6:%\\w+]] = OpConstant [[float]] 6\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFMul [[float]] [[ld]] [[float_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFMul %float %float_3 %2\n" +
- "%4 = OpFMul %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 3: fold vector fmul
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[v2float:%\\w+]] = OpTypeVector [[float]] 2\n" +
- "; CHECK: [[float_6:%\\w+]] = OpConstant [[float]] 6\n" +
- "; CHECK: [[v2float_6_6:%\\w+]] = OpConstantComposite [[v2float]] [[float_6]] [[float_6]]\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2float]]\n" +
- "; CHECK: %4 = OpFMul [[v2float]] [[ld]] [[v2float_6_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %var\n" +
- "%3 = OpFMul %v2float %2 %v2float_2_3\n" +
- "%4 = OpFMul %v2float %3 %v2float_3_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 4: fold double fmuls
- // (x * 3.0) * 2.0 = x * 6.0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[double_6:%\\w+]] = OpConstant [[double]] 6\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[double]]\n" +
- "; CHECK: %4 = OpFMul [[double]] [[ld]] [[double_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_double Function\n" +
- "%2 = OpLoad %double %var\n" +
- "%3 = OpFMul %double %2 %double_3\n" +
- "%4 = OpFMul %double %3 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 5: fold 32 bit imuls
- // (x * 3) * 2 = x * 6
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int_6:%\\w+]] = OpConstant [[int]] 6\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpIMul [[int]] [[ld]] [[int_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpIMul %int %2 %int_3\n" +
- "%4 = OpIMul %int %3 %int_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 6: fold 64 bit imuls
- // (x * 3) * 2 = x * 6
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64\n" +
- "; CHECK: [[long_6:%\\w+]] = OpConstant [[long]] 6\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpIMul [[long]] [[ld]] [[long_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpIMul %long %2 %long_3\n" +
- "%4 = OpIMul %long %3 %long_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 7: merge vector integer mults
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[v2int:%\\w+]] = OpTypeVector [[int]] 2\n" +
- "; CHECK: [[int_6:%\\w+]] = OpConstant [[int]] 6\n" +
- "; CHECK: [[v2int_6_6:%\\w+]] = OpConstantComposite [[v2int]] [[int_6]] [[int_6]]\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2int]]\n" +
- "; CHECK: %4 = OpIMul [[v2int]] [[ld]] [[v2int_6_6]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2int Function\n" +
- "%2 = OpLoad %v2int %var\n" +
- "%3 = OpIMul %v2int %2 %v2int_2_3\n" +
- "%4 = OpIMul %v2int %3 %v2int_3_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 8: merge fmul of fdiv
- // 2.0 * (2.0 / x) = 4.0 / x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_4:%\\w+]] = OpConstant [[float]] 4\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFDiv [[float]] [[float_4]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %float_2 %2\n" +
- "%4 = OpFMul %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 9: merge fmul of fdiv
- // (2.0 / x) * 2.0 = 4.0 / x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_4:%\\w+]] = OpConstant [[float]] 4\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFDiv [[float]] [[float_4]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFDiv %float %float_2 %2\n" +
- "%4 = OpFMul %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 10: Do not merge imul of sdiv
- // 4 * (x / 2)
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSDiv %int %2 %int_2\n" +
- "%4 = OpIMul %int %int_4 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 11: Do not merge imul of sdiv
- // (x / 2) * 4
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpSDiv %int %2 %int_2\n" +
- "%4 = OpIMul %int %3 %int_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 12: Do not merge imul of udiv
- // 4 * (x / 2)
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_uint Function\n" +
- "%2 = OpLoad %uint %var\n" +
- "%3 = OpUDiv %uint %2 %uint_2\n" +
- "%4 = OpIMul %uint %uint_4 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 13: Do not merge imul of udiv
- // (x / 2) * 4
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_uint Function\n" +
- "%2 = OpLoad %uint %var\n" +
- "%3 = OpUDiv %uint %2 %uint_2\n" +
- "%4 = OpIMul %uint %3 %uint_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 14: Don't fold
- // (x / 3) * 4
- InstructionFoldingCase<bool>(
- Header() +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_uint Function\n" +
- "%2 = OpLoad %uint %var\n" +
- "%3 = OpUDiv %uint %2 %uint_3\n" +
- "%4 = OpIMul %uint %3 %uint_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, false),
- // Test case 15: merge vector fmul of fdiv
- // (x / {2,2}) * {4,4} = x * {2,2}
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[v2float:%\\w+]] = OpTypeVector [[float]] 2\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[v2float_2_2:%\\w+]] = OpConstantComposite [[v2float]] [[float_2]] [[float_2]]\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2float]]\n" +
- "; CHECK: %4 = OpFMul [[v2float]] [[ld]] [[v2float_2_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2float Function\n" +
- "%2 = OpLoad %v2float %var\n" +
- "%3 = OpFDiv %v2float %2 %v2float_2_2\n" +
- "%4 = OpFMul %v2float %3 %v2float_4_4\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 16: merge vector imul of snegate
- // (-x) * {2,2} = x * {-2,-2}
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[v2int:%\\w+]] = OpTypeVector [[int]] 2{{[[:space:]]}}\n" +
- "; CHECK: OpConstant [[int]] -2147483648{{[[:space:]]}}\n" +
- "; CHECK: [[int_n2:%\\w+]] = OpConstant [[int]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[v2int_n2_n2:%\\w+]] = OpConstantComposite [[v2int]] [[int_n2]] [[int_n2]]\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2int]]\n" +
- "; CHECK: %4 = OpIMul [[v2int]] [[ld]] [[v2int_n2_n2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2int Function\n" +
- "%2 = OpLoad %v2int %var\n" +
- "%3 = OpSNegate %v2int %2\n" +
- "%4 = OpIMul %v2int %3 %v2int_2_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 17: merge vector imul of snegate
- // {2,2} * (-x) = x * {-2,-2}
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[v2int:%\\w+]] = OpTypeVector [[int]] 2{{[[:space:]]}}\n" +
- "; CHECK: OpConstant [[int]] -2147483648{{[[:space:]]}}\n" +
- "; CHECK: [[int_n2:%\\w+]] = OpConstant [[int]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[v2int_n2_n2:%\\w+]] = OpConstantComposite [[v2int]] [[int_n2]] [[int_n2]]\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[v2int]]\n" +
- "; CHECK: %4 = OpIMul [[v2int]] [[ld]] [[v2int_n2_n2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_v2int Function\n" +
- "%2 = OpLoad %v2int %var\n" +
- "%3 = OpSNegate %v2int %2\n" +
- "%4 = OpIMul %v2int %v2int_2_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 18: Fold OpVectorTimesScalar
- // {4,4} = OpVectorTimesScalar v2float {2,2} 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[v2float:%\\w+]] = OpTypeVector [[float]] 2\n" +
- "; CHECK: [[float_4:%\\w+]] = OpConstant [[float]] 4\n" +
- "; CHECK: [[v2float_4_4:%\\w+]] = OpConstantComposite [[v2float]] [[float_4]] [[float_4]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2float]] [[v2float_4_4]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesScalar %v2float %v2float_2_2 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 19: Fold OpVectorTimesScalar
- // {0,0} = OpVectorTimesScalar v2float v2float_null -1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[v2float:%\\w+]] = OpTypeVector [[float]] 2\n" +
- "; CHECK: [[v2float_null:%\\w+]] = OpConstantNull [[v2float]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2float]] [[v2float_null]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesScalar %v2float %v2float_null %float_n1\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 20: Fold OpVectorTimesScalar
- // {4,4} = OpVectorTimesScalar v2double {2,2} 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v2double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: [[double_4:%\\w+]] = OpConstant [[double]] 4\n" +
- "; CHECK: [[v2double_4_4:%\\w+]] = OpConstantComposite [[v2double]] [[double_4]] [[double_4]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2double]] [[v2double_4_4]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpVectorTimesScalar %v2double %v2double_2_2 %double_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 21: Fold OpVectorTimesScalar
- // {0,0} = OpVectorTimesScalar v2double {0,0} n
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v2double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: {{%\\w+}} = OpConstant [[double]] 0\n" +
- "; CHECK: [[double_0:%\\w+]] = OpConstant [[double]] 0\n" +
- "; CHECK: [[v2double_0_0:%\\w+]] = OpConstantComposite [[v2double]] [[double_0]] [[double_0]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2double]] [[v2double_0_0]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_double Function\n" +
- "%load = OpLoad %double %n\n" +
- "%2 = OpVectorTimesScalar %v2double %v2double_0_0 %load\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 22: Fold OpVectorTimesScalar
- // {0,0} = OpVectorTimesScalar v2double n 0
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[double:%\\w+]] = OpTypeFloat 64\n" +
- "; CHECK: [[v2double:%\\w+]] = OpTypeVector [[double]] 2\n" +
- "; CHECK: [[v2double_null:%\\w+]] = OpConstantNull [[v2double]]\n" +
- "; CHECK: %2 = OpCopyObject [[v2double]] [[v2double_null]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_v2double Function\n" +
- "%load = OpLoad %v2double %n\n" +
- "%2 = OpVectorTimesScalar %v2double %load %double_0\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, true),
- // Test case 23: merge fmul of fdiv
- // x * (y / x) = y
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[ldx:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: [[ldy:%\\w+]] = OpLoad [[float]] [[y:%\\w+]]\n" +
- "; CHECK: %5 = OpCopyObject [[float]] [[ldy]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %x\n" +
- "%3 = OpLoad %float %y\n" +
- "%4 = OpFDiv %float %3 %2\n" +
- "%5 = OpFMul %float %2 %4\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 5, true),
- // Test case 24: merge fmul of fdiv
- // (y / x) * x = y
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[ldx:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: [[ldy:%\\w+]] = OpLoad [[float]] [[y:%\\w+]]\n" +
- "; CHECK: %5 = OpCopyObject [[float]] [[ldy]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%x = OpVariable %_ptr_float Function\n" +
- "%y = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %x\n" +
- "%3 = OpLoad %float %y\n" +
- "%4 = OpFDiv %float %3 %2\n" +
- "%5 = OpFMul %float %4 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 5, true)
- ));
- 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{{[[:space:]]}}\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{{[[:space:]]}}\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(MergeGenericAddSub, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: merge of add of sub
- // (a - b) + b => a
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: %6 = OpCopyObject [[float]] %3\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var0 = OpVariable %_ptr_float Function\n" +
- "%var1 = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %var0\n" +
- "%4 = OpLoad %float %var1\n" +
- "%5 = OpFSub %float %3 %4\n" +
- "%6 = OpFAdd %float %5 %4\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 6, true),
- // Test case 1: merge of add of sub
- // b + (a - b) => a
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: %6 = OpCopyObject [[float]] %3\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var0 = OpVariable %_ptr_float Function\n" +
- "%var1 = OpVariable %_ptr_float Function\n" +
- "%3 = OpLoad %float %var0\n" +
- "%4 = OpLoad %float %var1\n" +
- "%5 = OpFSub %float %3 %4\n" +
- "%6 = OpFAdd %float %4 %5\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 6, true)
- ));
- INSTANTIATE_TEST_SUITE_P(FactorAddMul, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: factor of add of muls
- // (a * b) + (a * c) => a * (b + c)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[newadd:%\\w+]] = OpFAdd [[float]] %4 %5\n" +
- "; CHECK: %9 = OpFMul [[float]] %6 [[newadd]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var0 = OpVariable %_ptr_float Function\n" +
- "%var1 = OpVariable %_ptr_float Function\n" +
- "%var2 = OpVariable %_ptr_float Function\n" +
- "%4 = OpLoad %float %var0\n" +
- "%5 = OpLoad %float %var1\n" +
- "%6 = OpLoad %float %var2\n" +
- "%7 = OpFMul %float %6 %4\n" +
- "%8 = OpFMul %float %6 %5\n" +
- "%9 = OpFAdd %float %7 %8\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true),
- // Test case 1: factor of add of muls
- // (b * a) + (a * c) => a * (b + c)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[newadd:%\\w+]] = OpFAdd [[float]] %4 %5\n" +
- "; CHECK: %9 = OpFMul [[float]] %6 [[newadd]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var0 = OpVariable %_ptr_float Function\n" +
- "%var1 = OpVariable %_ptr_float Function\n" +
- "%var2 = OpVariable %_ptr_float Function\n" +
- "%4 = OpLoad %float %var0\n" +
- "%5 = OpLoad %float %var1\n" +
- "%6 = OpLoad %float %var2\n" +
- "%7 = OpFMul %float %4 %6\n" +
- "%8 = OpFMul %float %6 %5\n" +
- "%9 = OpFAdd %float %7 %8\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true),
- // Test case 2: factor of add of muls
- // (a * b) + (c * a) => a * (b + c)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[newadd:%\\w+]] = OpFAdd [[float]] %4 %5\n" +
- "; CHECK: %9 = OpFMul [[float]] %6 [[newadd]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var0 = OpVariable %_ptr_float Function\n" +
- "%var1 = OpVariable %_ptr_float Function\n" +
- "%var2 = OpVariable %_ptr_float Function\n" +
- "%4 = OpLoad %float %var0\n" +
- "%5 = OpLoad %float %var1\n" +
- "%6 = OpLoad %float %var2\n" +
- "%7 = OpFMul %float %6 %4\n" +
- "%8 = OpFMul %float %5 %6\n" +
- "%9 = OpFAdd %float %7 %8\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true),
- // Test case 3: factor of add of muls
- // (b * a) + (c * a) => a * (b + c)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[newadd:%\\w+]] = OpFAdd [[float]] %4 %5\n" +
- "; CHECK: %9 = OpFMul [[float]] %6 [[newadd]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var0 = OpVariable %_ptr_float Function\n" +
- "%var1 = OpVariable %_ptr_float Function\n" +
- "%var2 = OpVariable %_ptr_float Function\n" +
- "%4 = OpLoad %float %var0\n" +
- "%5 = OpLoad %float %var1\n" +
- "%6 = OpLoad %float %var2\n" +
- "%7 = OpFMul %float %4 %6\n" +
- "%8 = OpFMul %float %5 %6\n" +
- "%9 = OpFAdd %float %7 %8\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true)
- ));
- INSTANTIATE_TEST_SUITE_P(MergeSubTest, MatchingInstructionFoldingTest,
- ::testing::Values(
- // Test case 0: merge sub of negate
- // (-x) - 2 = -2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n2:%\\w+]] = OpConstant [[float]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFNegate %float %2\n" +
- "%4 = OpFSub %float %3 %float_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 1: merge sub of negate
- // 2 - (-x) = x + 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_2:%\\w+]] = OpConstant [[float]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFNegate %float %2\n" +
- "%4 = OpFSub %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 2: merge sub of negate
- // (-x) - 2 = -2 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_n2:%\\w+]] = OpConstant [[long]] -2{{[[:space:]]}}\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpISub [[long]] [[long_n2]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpSNegate %long %2\n" +
- "%4 = OpISub %long %3 %long_2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 3: merge sub of negate
- // 2 - (-x) = x + 2
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[long:%\\w+]] = OpTypeInt 64 1\n" +
- "; CHECK: [[long_2:%\\w+]] = OpConstant [[long]] 2\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[long]]\n" +
- "; CHECK: %4 = OpIAdd [[long]] [[ld]] [[long_2]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_long Function\n" +
- "%2 = OpLoad %long %var\n" +
- "%3 = OpSNegate %long %2\n" +
- "%4 = OpISub %long %long_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 4: merge add of subtract
- // (x + 2) - 1 = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %2 %float_2\n" +
- "%4 = OpFSub %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 5: merge add of subtract
- // (2 + x) - 1 = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %float_2 %2\n" +
- "%4 = OpFSub %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 6: merge add of subtract
- // 2 - (x + 1) = 1 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_1]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %2 %float_1\n" +
- "%4 = OpFSub %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 7: merge add of subtract
- // 2 - (1 + x) = 1 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_1]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFAdd %float %float_1 %2\n" +
- "%4 = OpFSub %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 8: merge subtract of subtract
- // (x - 2) - 1 = x - 3
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_3:%\\w+]] = OpConstant [[float]] 3\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[ld]] [[float_3]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %2 %float_2\n" +
- "%4 = OpFSub %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 9: merge subtract of subtract
- // (2 - x) - 1 = 1 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_1]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %float_2 %2\n" +
- "%4 = OpFSub %float %3 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 10: merge subtract of subtract
- // 2 - (x - 1) = 3 - x
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_3:%\\w+]] = OpConstant [[float]] 3\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFSub [[float]] [[float_3]] [[ld]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %2 %float_1\n" +
- "%4 = OpFSub %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 11: merge subtract of subtract
- // 1 - (2 - x) = x + (-1)
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_n1:%\\w+]] = OpConstant [[float]] -1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_n1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %float_2 %2\n" +
- "%4 = OpFSub %float %float_1 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 12: merge subtract of subtract
- // 2 - (1 - x) = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[float:%\\w+]] = OpTypeFloat 32\n" +
- "; CHECK: [[float_1:%\\w+]] = OpConstant [[float]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[float]]\n" +
- "; CHECK: %4 = OpFAdd [[float]] [[ld]] [[float_1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_float Function\n" +
- "%2 = OpLoad %float %var\n" +
- "%3 = OpFSub %float %float_1 %2\n" +
- "%4 = OpFSub %float %float_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true),
- // Test case 13: merge subtract of subtract with mixed types.
- // 2 - (1 - x) = x + 1
- InstructionFoldingCase<bool>(
- Header() +
- "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
- "; CHECK: [[int_1:%\\w+]] = OpConstant [[int]] 1\n" +
- "; CHECK: [[ld:%\\w+]] = OpLoad [[int]]\n" +
- "; CHECK: %4 = OpIAdd [[int]] [[ld]] [[int_1]]\n" +
- "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%var = OpVariable %_ptr_int Function\n" +
- "%2 = OpLoad %int %var\n" +
- "%3 = OpISub %int %uint_1 %2\n" +
- "%4 = OpISub %int %int_2 %3\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 4, true)
- ));
- 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)
- ));
- using EntryPointFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<bool>>;
- TEST_P(EntryPointFoldingTest, Case) {
- const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
- // Fold the instruction to test.
- Instruction* inst = nullptr;
- inst = &*context->module()->entry_points().begin();
- assert(inst && "Invalid test. Could not find entry point instruction to fold.");
- std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- EXPECT_EQ(succeeded, tc.expected_result);
- if (succeeded) {
- Match(tc.test_body, context.get());
- }
- }
- INSTANTIATE_TEST_SUITE_P(OpEntryPointFoldingTest, EntryPointFoldingTest,
- ::testing::Values(
- // Test case 0: Basic test 1
- InstructionFoldingCase<bool>(std::string() +
- "; CHECK: OpEntryPoint Fragment %2 \"main\" %3\n" +
- "OpCapability Shader\n" +
- "%1 = OpExtInstImport \"GLSL.std.450\"\n" +
- "OpMemoryModel Logical GLSL450\n" +
- "OpEntryPoint Fragment %2 \"main\" %3 %3 %3\n" +
- "OpExecutionMode %2 OriginUpperLeft\n" +
- "OpSource GLSL 430\n" +
- "OpDecorate %3 Location 0\n" +
- "%void = OpTypeVoid\n" +
- "%5 = OpTypeFunction %void\n" +
- "%float = OpTypeFloat 32\n" +
- "%v4float = OpTypeVector %float 4\n" +
- "%_ptr_Output_v4float = OpTypePointer Output %v4float\n" +
- "%3 = OpVariable %_ptr_Output_v4float Output\n" +
- "%int = OpTypeInt 32 1\n" +
- "%int_0 = OpConstant %int 0\n" +
- "%_ptr_PushConstant_v4float = OpTypePointer PushConstant %v4float\n" +
- "%2 = OpFunction %void None %5\n" +
- "%12 = OpLabel\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true),
- InstructionFoldingCase<bool>(std::string() +
- "; CHECK: OpEntryPoint Fragment %2 \"main\" %3 %4\n" +
- "OpCapability Shader\n" +
- "%1 = OpExtInstImport \"GLSL.std.450\"\n" +
- "OpMemoryModel Logical GLSL450\n" +
- "OpEntryPoint Fragment %2 \"main\" %3 %4 %3\n" +
- "OpExecutionMode %2 OriginUpperLeft\n" +
- "OpSource GLSL 430\n" +
- "OpDecorate %3 Location 0\n" +
- "%void = OpTypeVoid\n" +
- "%5 = OpTypeFunction %void\n" +
- "%float = OpTypeFloat 32\n" +
- "%v4float = OpTypeVector %float 4\n" +
- "%_ptr_Output_v4float = OpTypePointer Output %v4float\n" +
- "%3 = OpVariable %_ptr_Output_v4float Output\n" +
- "%4 = OpVariable %_ptr_Output_v4float Output\n" +
- "%int = OpTypeInt 32 1\n" +
- "%int_0 = OpConstant %int 0\n" +
- "%_ptr_PushConstant_v4float = OpTypePointer PushConstant %v4float\n" +
- "%2 = OpFunction %void None %5\n" +
- "%12 = OpLabel\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true),
- InstructionFoldingCase<bool>(std::string() +
- "; CHECK: OpEntryPoint Fragment %2 \"main\" %4 %3\n" +
- "OpCapability Shader\n" +
- "%1 = OpExtInstImport \"GLSL.std.450\"\n" +
- "OpMemoryModel Logical GLSL450\n" +
- "OpEntryPoint Fragment %2 \"main\" %4 %4 %3\n" +
- "OpExecutionMode %2 OriginUpperLeft\n" +
- "OpSource GLSL 430\n" +
- "OpDecorate %3 Location 0\n" +
- "%void = OpTypeVoid\n" +
- "%5 = OpTypeFunction %void\n" +
- "%float = OpTypeFloat 32\n" +
- "%v4float = OpTypeVector %float 4\n" +
- "%_ptr_Output_v4float = OpTypePointer Output %v4float\n" +
- "%3 = OpVariable %_ptr_Output_v4float Output\n" +
- "%4 = OpVariable %_ptr_Output_v4float Output\n" +
- "%int = OpTypeInt 32 1\n" +
- "%int_0 = OpConstant %int 0\n" +
- "%_ptr_PushConstant_v4float = OpTypePointer PushConstant %v4float\n" +
- "%2 = OpFunction %void None %5\n" +
- "%12 = OpLabel\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n",
- 9, true)
- ));
- using SPV14FoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<bool>>;
- TEST_P(SPV14FoldingTest, Case) {
- const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_4, 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(SPV14FoldingTest, SPV14FoldingTest,
- ::testing::Values(
- // Test case 0: select vectors with scalar condition.
- InstructionFoldingCase<bool>(std::string() +
- "; CHECK-NOT: OpSelect\n" +
- "; CHECK: %3 = OpCopyObject {{%\\w+}} %1\n" +
- "OpCapability Shader\n" +
- "OpCapability Linkage\n" +
- "%void = OpTypeVoid\n" +
- "%bool = OpTypeBool\n" +
- "%true = OpConstantTrue %bool\n" +
- "%int = OpTypeInt 32 0\n" +
- "%int4 = OpTypeVector %int 4\n" +
- "%int_0 = OpConstant %int 0\n" +
- "%int_1 = OpConstant %int 1\n" +
- "%1 = OpUndef %int4\n" +
- "%2 = OpUndef %int4\n" +
- "%void_fn = OpTypeFunction %void\n" +
- "%func = OpFunction %void None %void_fn\n" +
- "%entry = OpLabel\n" +
- "%3 = OpSelect %int4 %true %1 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 3, true),
- // Test case 1: select struct with scalar condition.
- InstructionFoldingCase<bool>(std::string() +
- "; CHECK-NOT: OpSelect\n" +
- "; CHECK: %3 = OpCopyObject {{%\\w+}} %2\n" +
- "OpCapability Shader\n" +
- "OpCapability Linkage\n" +
- "%void = OpTypeVoid\n" +
- "%bool = OpTypeBool\n" +
- "%true = OpConstantFalse %bool\n" +
- "%int = OpTypeInt 32 0\n" +
- "%struct = OpTypeStruct %int %int %int %int\n" +
- "%int_0 = OpConstant %int 0\n" +
- "%int_1 = OpConstant %int 1\n" +
- "%1 = OpUndef %struct\n" +
- "%2 = OpUndef %struct\n" +
- "%void_fn = OpTypeFunction %void\n" +
- "%func = OpFunction %void None %void_fn\n" +
- "%entry = OpLabel\n" +
- "%3 = OpSelect %struct %true %1 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 3, true),
- // Test case 1: select array with scalar condition.
- InstructionFoldingCase<bool>(std::string() +
- "; CHECK-NOT: OpSelect\n" +
- "; CHECK: %3 = OpCopyObject {{%\\w+}} %2\n" +
- "OpCapability Shader\n" +
- "OpCapability Linkage\n" +
- "%void = OpTypeVoid\n" +
- "%bool = OpTypeBool\n" +
- "%true = OpConstantFalse %bool\n" +
- "%int = OpTypeInt 32 0\n" +
- "%int_0 = OpConstant %int 0\n" +
- "%int_1 = OpConstant %int 1\n" +
- "%int_4 = OpConstant %int 4\n" +
- "%array = OpTypeStruct %int %int %int %int\n" +
- "%1 = OpUndef %array\n" +
- "%2 = OpUndef %array\n" +
- "%void_fn = OpTypeFunction %void\n" +
- "%func = OpFunction %void None %void_fn\n" +
- "%entry = OpLabel\n" +
- "%3 = OpSelect %array %true %1 %2\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 3, true)
- ));
- std::string FloatControlsHeader(const std::string& capabilities) {
- std::string header = R"(
- OpCapability Shader
- )" + capabilities + R"(
- %void = OpTypeVoid
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %float_1 = OpConstant %float 1
- %void_fn = OpTypeFunction %void
- %func = OpFunction %void None %void_fn
- %entry = OpLabel
- )";
- return header;
- }
- using FloatControlsFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<bool>>;
- TEST_P(FloatControlsFoldingTest, Case) {
- const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_4, 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(FloatControlsFoldingTest, FloatControlsFoldingTest,
- ::testing::Values(
- // Test case 0: no folding with DenormPreserve
- InstructionFoldingCase<bool>(FloatControlsHeader("OpCapability DenormPreserve") +
- "%1 = OpFAdd %float %float_0 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 1, false),
- // Test case 1: no folding with DenormFlushToZero
- InstructionFoldingCase<bool>(FloatControlsHeader("OpCapability DenormFlushToZero") +
- "%1 = OpFAdd %float %float_0 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 1, false),
- // Test case 2: no folding with SignedZeroInfNanPreserve
- InstructionFoldingCase<bool>(FloatControlsHeader("OpCapability SignedZeroInfNanPreserve") +
- "%1 = OpFAdd %float %float_0 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 1, false),
- // Test case 3: no folding with RoundingModeRTE
- InstructionFoldingCase<bool>(FloatControlsHeader("OpCapability RoundingModeRTE") +
- "%1 = OpFAdd %float %float_0 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 1, false),
- // Test case 4: no folding with RoundingModeRTZ
- InstructionFoldingCase<bool>(FloatControlsHeader("OpCapability RoundingModeRTZ") +
- "%1 = OpFAdd %float %float_0 %float_1\n" +
- "OpReturn\n" +
- "OpFunctionEnd\n"
- ,
- 1, false)
- ));
- std::string ImageOperandsTestBody(const std::string& image_instruction) {
- std::string body = R"(
- OpCapability Shader
- OpCapability ImageGatherExtended
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpDecorate %Texture DescriptorSet 0
- OpDecorate %Texture Binding 0
- %int = OpTypeInt 32 1
- %int_n1 = OpConstant %int -1
- %5 = OpConstant %int 0
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
- %type_sampled_image = OpTypeSampledImage %type_2d_image
- %type_sampler = OpTypeSampler
- %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
- %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
- %_ptr_int = OpTypePointer Function %int
- %v2int = OpTypeVector %int 2
- %10 = OpTypeVector %float 4
- %void = OpTypeVoid
- %22 = OpTypeFunction %void
- %v2float = OpTypeVector %float 2
- %v3int = OpTypeVector %int 3
- %Texture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
- %gSampler = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
- %101 = OpConstantComposite %v2int %int_n1 %int_n1
- %20 = OpConstantComposite %v2float %float_0 %float_0
- %main = OpFunction %void None %22
- %23 = OpLabel
- %var = OpVariable %_ptr_int Function
- %88 = OpLoad %type_2d_image %Texture
- %val = OpLoad %int %var
- %sampler = OpLoad %type_sampler %gSampler
- %26 = OpSampledImage %type_sampled_image %88 %sampler
- )" + image_instruction + R"(
- OpReturn
- OpFunctionEnd
- )";
- return body;
- }
- INSTANTIATE_TEST_SUITE_P(ImageOperandsBitmaskFoldingTest, MatchingInstructionWithNoResultFoldingTest,
- ::testing::Values(
- // Test case 0: OpImageFetch without Offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- "%89 = OpImageFetch %10 %88 %101 Lod %5 \n")
- , 89, false),
- // Test case 1: OpImageFetch with non-const offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- "%89 = OpImageFetch %10 %88 %101 Lod|Offset %5 %val \n")
- , 89, false),
- // Test case 2: OpImageFetch with Lod and Offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " %89 = OpImageFetch %10 %88 %101 Lod|Offset %5 %101 \n"
- "; CHECK: %89 = OpImageFetch %10 %88 %101 Lod|ConstOffset %5 %101 \n")
- , 89, true),
- // Test case 3: OpImageFetch with Bias and Offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " %89 = OpImageFetch %10 %88 %101 Bias|Offset %5 %101 \n"
- "; CHECK: %89 = OpImageFetch %10 %88 %101 Bias|ConstOffset %5 %101 \n")
- , 89, true),
- // Test case 4: OpImageFetch with Grad and Offset.
- // Grad adds 2 operands to the instruction.
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " %89 = OpImageFetch %10 %88 %101 Grad|Offset %5 %5 %101 \n"
- "; CHECK: %89 = OpImageFetch %10 %88 %101 Grad|ConstOffset %5 %5 %101 \n")
- , 89, true),
- // Test case 5: OpImageFetch with Offset and MinLod.
- // This is an example of a case where the bitmask bit-offset is larger than
- // that of the Offset.
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " %89 = OpImageFetch %10 %88 %101 Offset|MinLod %101 %5 \n"
- "; CHECK: %89 = OpImageFetch %10 %88 %101 ConstOffset|MinLod %101 %5 \n")
- , 89, true),
- // Test case 6: OpImageGather with constant Offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " %89 = OpImageGather %10 %26 %20 %5 Offset %101 \n"
- "; CHECK: %89 = OpImageGather %10 %26 %20 %5 ConstOffset %101 \n")
- , 89, true),
- // Test case 7: OpImageWrite with constant Offset
- InstructionFoldingCase<bool>(ImageOperandsTestBody(
- " OpImageWrite %88 %5 %101 Offset %101 \n"
- "; CHECK: OpImageWrite %88 %5 %101 ConstOffset %101 \n")
- , 0 /* No result-id */, true)
- ));
- } // namespace
- } // namespace opt
- } // namespace spvtools
|