val_ext_inst_test.cpp 290 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574
  1. // Copyright (c) 2017 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Tests validation rules of GLSL.450.std and OpenCL.std extended instructions.
  15. // Doesn't test OpenCL.std vector size 2, 3, 4, 8 or 16 rules (not supported
  16. // by standard SPIR-V).
  17. #include <sstream>
  18. #include <string>
  19. #include <vector>
  20. #include "gmock/gmock.h"
  21. #include "test/unit_spirv.h"
  22. #include "test/val/val_fixtures.h"
  23. namespace spvtools {
  24. namespace val {
  25. namespace {
  26. using ::testing::Eq;
  27. using ::testing::HasSubstr;
  28. using ::testing::Not;
  29. using ValidateExtInst = spvtest::ValidateBase<bool>;
  30. using ValidateGlslStd450SqrtLike = spvtest::ValidateBase<std::string>;
  31. using ValidateGlslStd450FMinLike = spvtest::ValidateBase<std::string>;
  32. using ValidateGlslStd450FClampLike = spvtest::ValidateBase<std::string>;
  33. using ValidateGlslStd450SAbsLike = spvtest::ValidateBase<std::string>;
  34. using ValidateGlslStd450UMinLike = spvtest::ValidateBase<std::string>;
  35. using ValidateGlslStd450UClampLike = spvtest::ValidateBase<std::string>;
  36. using ValidateGlslStd450SinLike = spvtest::ValidateBase<std::string>;
  37. using ValidateGlslStd450PowLike = spvtest::ValidateBase<std::string>;
  38. using ValidateGlslStd450Pack = spvtest::ValidateBase<std::string>;
  39. using ValidateGlslStd450Unpack = spvtest::ValidateBase<std::string>;
  40. using ValidateOpenCLStdSqrtLike = spvtest::ValidateBase<std::string>;
  41. using ValidateOpenCLStdFMinLike = spvtest::ValidateBase<std::string>;
  42. using ValidateOpenCLStdFClampLike = spvtest::ValidateBase<std::string>;
  43. using ValidateOpenCLStdSAbsLike = spvtest::ValidateBase<std::string>;
  44. using ValidateOpenCLStdUMinLike = spvtest::ValidateBase<std::string>;
  45. using ValidateOpenCLStdUClampLike = spvtest::ValidateBase<std::string>;
  46. using ValidateOpenCLStdUMul24Like = spvtest::ValidateBase<std::string>;
  47. using ValidateOpenCLStdUMad24Like = spvtest::ValidateBase<std::string>;
  48. using ValidateOpenCLStdLengthLike = spvtest::ValidateBase<std::string>;
  49. using ValidateOpenCLStdDistanceLike = spvtest::ValidateBase<std::string>;
  50. using ValidateOpenCLStdNormalizeLike = spvtest::ValidateBase<std::string>;
  51. using ValidateOpenCLStdVStoreHalfLike = spvtest::ValidateBase<std::string>;
  52. using ValidateOpenCLStdVLoadHalfLike = spvtest::ValidateBase<std::string>;
  53. using ValidateOpenCLStdFractLike = spvtest::ValidateBase<std::string>;
  54. using ValidateOpenCLStdFrexpLike = spvtest::ValidateBase<std::string>;
  55. using ValidateOpenCLStdLdexpLike = spvtest::ValidateBase<std::string>;
  56. using ValidateOpenCLStdUpsampleLike = spvtest::ValidateBase<std::string>;
  57. using ValidateClspvReflection = spvtest::ValidateBase<bool>;
  58. // Returns number of components in Pack/Unpack extended instructions.
  59. // |ext_inst_name| is expected to be of the format "PackHalf2x16".
  60. // Number of components is assumed to be single-digit.
  61. uint32_t GetPackedNumComponents(const std::string& ext_inst_name) {
  62. const size_t x_index = ext_inst_name.find_last_of('x');
  63. const std::string num_components_str =
  64. ext_inst_name.substr(x_index - 1, x_index);
  65. return uint32_t(std::stoul(num_components_str));
  66. }
  67. // Returns packed bit width in Pack/Unpack extended instructions.
  68. // |ext_inst_name| is expected to be of the format "PackHalf2x16".
  69. uint32_t GetPackedBitWidth(const std::string& ext_inst_name) {
  70. const size_t x_index = ext_inst_name.find_last_of('x');
  71. const std::string packed_bit_width_str = ext_inst_name.substr(x_index + 1);
  72. return uint32_t(std::stoul(packed_bit_width_str));
  73. }
  74. std::string GenerateShaderCode(
  75. const std::string& body,
  76. const std::string& capabilities_and_extensions = "",
  77. const std::string& execution_model = "Fragment") {
  78. std::ostringstream ss;
  79. ss << R"(
  80. OpCapability Shader
  81. OpCapability Float16
  82. OpCapability Float64
  83. OpCapability Int16
  84. OpCapability Int64
  85. )";
  86. ss << capabilities_and_extensions;
  87. ss << "%extinst = OpExtInstImport \"GLSL.std.450\"\n";
  88. ss << "OpMemoryModel Logical GLSL450\n";
  89. ss << "OpEntryPoint " << execution_model << " %main \"main\""
  90. << " %f32_output"
  91. << " %f32vec2_output"
  92. << " %u32_output"
  93. << " %u32vec2_output"
  94. << " %u64_output"
  95. << " %f32_input"
  96. << " %f32vec2_input"
  97. << " %u32_input"
  98. << " %u32vec2_input"
  99. << " %u64_input"
  100. << "\n";
  101. if (execution_model == "Fragment") {
  102. ss << "OpExecutionMode %main OriginUpperLeft\n";
  103. }
  104. ss << R"(
  105. %void = OpTypeVoid
  106. %func = OpTypeFunction %void
  107. %bool = OpTypeBool
  108. %f16 = OpTypeFloat 16
  109. %f32 = OpTypeFloat 32
  110. %f64 = OpTypeFloat 64
  111. %u32 = OpTypeInt 32 0
  112. %s32 = OpTypeInt 32 1
  113. %u64 = OpTypeInt 64 0
  114. %s64 = OpTypeInt 64 1
  115. %u16 = OpTypeInt 16 0
  116. %s16 = OpTypeInt 16 1
  117. %f32vec2 = OpTypeVector %f32 2
  118. %f32vec3 = OpTypeVector %f32 3
  119. %f32vec4 = OpTypeVector %f32 4
  120. %f64vec2 = OpTypeVector %f64 2
  121. %f64vec3 = OpTypeVector %f64 3
  122. %f64vec4 = OpTypeVector %f64 4
  123. %u32vec2 = OpTypeVector %u32 2
  124. %u32vec3 = OpTypeVector %u32 3
  125. %s32vec2 = OpTypeVector %s32 2
  126. %u32vec4 = OpTypeVector %u32 4
  127. %s32vec4 = OpTypeVector %s32 4
  128. %u64vec2 = OpTypeVector %u64 2
  129. %s64vec2 = OpTypeVector %s64 2
  130. %f64mat22 = OpTypeMatrix %f64vec2 2
  131. %f32mat22 = OpTypeMatrix %f32vec2 2
  132. %f32mat23 = OpTypeMatrix %f32vec2 3
  133. %f32mat32 = OpTypeMatrix %f32vec3 2
  134. %f32mat33 = OpTypeMatrix %f32vec3 3
  135. %f32_0 = OpConstant %f32 0
  136. %f32_1 = OpConstant %f32 1
  137. %f32_2 = OpConstant %f32 2
  138. %f32_3 = OpConstant %f32 3
  139. %f32_4 = OpConstant %f32 4
  140. %f32_h = OpConstant %f32 0.5
  141. %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
  142. %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
  143. %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
  144. %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
  145. %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
  146. %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
  147. %f64_0 = OpConstant %f64 0
  148. %f64_1 = OpConstant %f64 1
  149. %f64_2 = OpConstant %f64 2
  150. %f64_3 = OpConstant %f64 3
  151. %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
  152. %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
  153. %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
  154. %f16_0 = OpConstant %f16 0
  155. %f16_1 = OpConstant %f16 1
  156. %f16_h = OpConstant %f16 0.5
  157. %u32_0 = OpConstant %u32 0
  158. %u32_1 = OpConstant %u32 1
  159. %u32_2 = OpConstant %u32 2
  160. %u32_3 = OpConstant %u32 3
  161. %s32_0 = OpConstant %s32 0
  162. %s32_1 = OpConstant %s32 1
  163. %s32_2 = OpConstant %s32 2
  164. %s32_3 = OpConstant %s32 3
  165. %u64_0 = OpConstant %u64 0
  166. %u64_1 = OpConstant %u64 1
  167. %u64_2 = OpConstant %u64 2
  168. %u64_3 = OpConstant %u64 3
  169. %s64_0 = OpConstant %s64 0
  170. %s64_1 = OpConstant %s64 1
  171. %s64_2 = OpConstant %s64 2
  172. %s64_3 = OpConstant %s64 3
  173. %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
  174. %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
  175. %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
  176. %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
  177. %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
  178. %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
  179. %s64vec2_01 = OpConstantComposite %s64vec2 %s64_0 %s64_1
  180. %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
  181. %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
  182. %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
  183. %f32_ptr_output = OpTypePointer Output %f32
  184. %f32vec2_ptr_output = OpTypePointer Output %f32vec2
  185. %u32_ptr_output = OpTypePointer Output %u32
  186. %u32vec2_ptr_output = OpTypePointer Output %u32vec2
  187. %u64_ptr_output = OpTypePointer Output %u64
  188. %f32_output = OpVariable %f32_ptr_output Output
  189. %f32vec2_output = OpVariable %f32vec2_ptr_output Output
  190. %u32_output = OpVariable %u32_ptr_output Output
  191. %u32vec2_output = OpVariable %u32vec2_ptr_output Output
  192. %u64_output = OpVariable %u64_ptr_output Output
  193. %f32_ptr_input = OpTypePointer Input %f32
  194. %f32vec2_ptr_input = OpTypePointer Input %f32vec2
  195. %u32_ptr_input = OpTypePointer Input %u32
  196. %u32vec2_ptr_input = OpTypePointer Input %u32vec2
  197. %u64_ptr_input = OpTypePointer Input %u64
  198. %f32_input = OpVariable %f32_ptr_input Input
  199. %f32vec2_input = OpVariable %f32vec2_ptr_input Input
  200. %u32_input = OpVariable %u32_ptr_input Input
  201. %u32vec2_input = OpVariable %u32vec2_ptr_input Input
  202. %u64_input = OpVariable %u64_ptr_input Input
  203. %struct_f16_u16 = OpTypeStruct %f16 %u16
  204. %struct_f32_f32 = OpTypeStruct %f32 %f32
  205. %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
  206. %struct_f32_u32 = OpTypeStruct %f32 %u32
  207. %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
  208. %struct_u32_f32 = OpTypeStruct %u32 %f32
  209. %struct_u32_u32 = OpTypeStruct %u32 %u32
  210. %struct_f32_f64 = OpTypeStruct %f32 %f64
  211. %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
  212. %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
  213. %main = OpFunction %void None %func
  214. %main_entry = OpLabel
  215. )";
  216. ss << body;
  217. ss << R"(
  218. OpReturn
  219. OpFunctionEnd)";
  220. return ss.str();
  221. }
  222. std::string GenerateKernelCode(
  223. const std::string& body,
  224. const std::string& capabilities_and_extensions = "",
  225. const std::string& memory_model = "Physical32") {
  226. std::ostringstream ss;
  227. ss << R"(
  228. OpCapability Addresses
  229. OpCapability Kernel
  230. OpCapability Linkage
  231. OpCapability GenericPointer
  232. OpCapability Int8
  233. OpCapability Int16
  234. OpCapability Int64
  235. OpCapability Float16
  236. OpCapability Float64
  237. OpCapability Vector16
  238. OpCapability Matrix
  239. )";
  240. ss << capabilities_and_extensions;
  241. ss << "%extinst = OpExtInstImport \"OpenCL.std\"\n";
  242. ss << "OpMemoryModel " << memory_model << " OpenCL\n";
  243. ss << R"(
  244. %void = OpTypeVoid
  245. %func = OpTypeFunction %void
  246. %bool = OpTypeBool
  247. %f16 = OpTypeFloat 16
  248. %f32 = OpTypeFloat 32
  249. %f64 = OpTypeFloat 64
  250. %u32 = OpTypeInt 32 0
  251. %u64 = OpTypeInt 64 0
  252. %u16 = OpTypeInt 16 0
  253. %u8 = OpTypeInt 8 0
  254. %f32vec2 = OpTypeVector %f32 2
  255. %f32vec3 = OpTypeVector %f32 3
  256. %f32vec4 = OpTypeVector %f32 4
  257. %f32vec8 = OpTypeVector %f32 8
  258. %f16vec8 = OpTypeVector %f16 8
  259. %f32vec16 = OpTypeVector %f32 16
  260. %f64vec2 = OpTypeVector %f64 2
  261. %f64vec3 = OpTypeVector %f64 3
  262. %f64vec4 = OpTypeVector %f64 4
  263. %u32vec2 = OpTypeVector %u32 2
  264. %u32vec3 = OpTypeVector %u32 3
  265. %u32vec4 = OpTypeVector %u32 4
  266. %u32vec8 = OpTypeVector %u32 8
  267. %u64vec2 = OpTypeVector %u64 2
  268. %f64mat22 = OpTypeMatrix %f64vec2 2
  269. %f32mat22 = OpTypeMatrix %f32vec2 2
  270. %f32mat23 = OpTypeMatrix %f32vec2 3
  271. %f32mat32 = OpTypeMatrix %f32vec3 2
  272. %f32mat33 = OpTypeMatrix %f32vec3 3
  273. %f32_0 = OpConstant %f32 0
  274. %f32_1 = OpConstant %f32 1
  275. %f32_2 = OpConstant %f32 2
  276. %f32_3 = OpConstant %f32 3
  277. %f32_4 = OpConstant %f32 4
  278. %f32_h = OpConstant %f32 0.5
  279. %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
  280. %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
  281. %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
  282. %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
  283. %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
  284. %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
  285. %f32vec8_01010101 = OpConstantComposite %f32vec8 %f32_0 %f32_1 %f32_0 %f32_1 %f32_0 %f32_1 %f32_0 %f32_1
  286. %f64_0 = OpConstant %f64 0
  287. %f64_1 = OpConstant %f64 1
  288. %f64_2 = OpConstant %f64 2
  289. %f64_3 = OpConstant %f64 3
  290. %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
  291. %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
  292. %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
  293. %f16_0 = OpConstant %f16 0
  294. %f16_1 = OpConstant %f16 1
  295. %u8_0 = OpConstant %u8 0
  296. %u8_1 = OpConstant %u8 1
  297. %u8_2 = OpConstant %u8 2
  298. %u8_3 = OpConstant %u8 3
  299. %u16_0 = OpConstant %u16 0
  300. %u16_1 = OpConstant %u16 1
  301. %u16_2 = OpConstant %u16 2
  302. %u16_3 = OpConstant %u16 3
  303. %u32_0 = OpConstant %u32 0
  304. %u32_1 = OpConstant %u32 1
  305. %u32_2 = OpConstant %u32 2
  306. %u32_3 = OpConstant %u32 3
  307. %u32_256 = OpConstant %u32 256
  308. %u64_0 = OpConstant %u64 0
  309. %u64_1 = OpConstant %u64 1
  310. %u64_2 = OpConstant %u64 2
  311. %u64_3 = OpConstant %u64 3
  312. %u64_256 = OpConstant %u64 256
  313. %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
  314. %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
  315. %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
  316. %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
  317. %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
  318. %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
  319. %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
  320. %struct_f32_f32 = OpTypeStruct %f32 %f32
  321. %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
  322. %struct_f32_u32 = OpTypeStruct %f32 %u32
  323. %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
  324. %struct_u32_f32 = OpTypeStruct %u32 %f32
  325. %struct_u32_u32 = OpTypeStruct %u32 %u32
  326. %struct_f32_f64 = OpTypeStruct %f32 %f64
  327. %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
  328. %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
  329. %f16vec8_ptr_workgroup = OpTypePointer Workgroup %f16vec8
  330. %f16vec8_workgroup = OpVariable %f16vec8_ptr_workgroup Workgroup
  331. %f16_ptr_workgroup = OpTypePointer Workgroup %f16
  332. %u32vec8_ptr_workgroup = OpTypePointer Workgroup %u32vec8
  333. %u32vec8_workgroup = OpVariable %u32vec8_ptr_workgroup Workgroup
  334. %u32_ptr_workgroup = OpTypePointer Workgroup %u32
  335. %f32vec8_ptr_workgroup = OpTypePointer Workgroup %f32vec8
  336. %f32vec8_workgroup = OpVariable %f32vec8_ptr_workgroup Workgroup
  337. %f32_ptr_workgroup = OpTypePointer Workgroup %f32
  338. %u32arr = OpTypeArray %u32 %u32_256
  339. %u32arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %u32arr
  340. %u32arr_cross_workgroup = OpVariable %u32arr_ptr_cross_workgroup CrossWorkgroup
  341. %u32_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %u32
  342. %f32arr = OpTypeArray %f32 %u32_256
  343. %f32arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32arr
  344. %f32arr_cross_workgroup = OpVariable %f32arr_ptr_cross_workgroup CrossWorkgroup
  345. %f32_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32
  346. %f32vec2arr = OpTypeArray %f32vec2 %u32_256
  347. %f32vec2arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32vec2arr
  348. %f32vec2arr_cross_workgroup = OpVariable %f32vec2arr_ptr_cross_workgroup CrossWorkgroup
  349. %f32vec2_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32vec2
  350. %struct_arr = OpTypeArray %struct_f32_f32 %u32_256
  351. %struct_arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %struct_arr
  352. %struct_arr_cross_workgroup = OpVariable %struct_arr_ptr_cross_workgroup CrossWorkgroup
  353. %struct_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %struct_f32_f32
  354. %f16vec8_ptr_uniform_constant = OpTypePointer UniformConstant %f16vec8
  355. %f16vec8_uniform_constant = OpVariable %f16vec8_ptr_uniform_constant UniformConstant
  356. %f16_ptr_uniform_constant = OpTypePointer UniformConstant %f16
  357. %u32vec8_ptr_uniform_constant = OpTypePointer UniformConstant %u32vec8
  358. %u32vec8_uniform_constant = OpVariable %u32vec8_ptr_uniform_constant UniformConstant
  359. %u32_ptr_uniform_constant = OpTypePointer UniformConstant %u32
  360. %f32vec8_ptr_uniform_constant = OpTypePointer UniformConstant %f32vec8
  361. %f32vec8_uniform_constant = OpVariable %f32vec8_ptr_uniform_constant UniformConstant
  362. %f32_ptr_uniform_constant = OpTypePointer UniformConstant %f32
  363. %f16vec8_ptr_input = OpTypePointer Input %f16vec8
  364. %f16vec8_input = OpVariable %f16vec8_ptr_input Input
  365. %f16_ptr_input = OpTypePointer Input %f16
  366. %u32vec8_ptr_input = OpTypePointer Input %u32vec8
  367. %u32vec8_input = OpVariable %u32vec8_ptr_input Input
  368. %u32_ptr_input = OpTypePointer Input %u32
  369. %f32_ptr_generic = OpTypePointer Generic %f32
  370. %u32_ptr_generic = OpTypePointer Generic %u32
  371. %f32_ptr_function = OpTypePointer Function %f32
  372. %f32vec2_ptr_function = OpTypePointer Function %f32vec2
  373. %u32_ptr_function = OpTypePointer Function %u32
  374. %u64_ptr_function = OpTypePointer Function %u64
  375. %u32vec2_ptr_function = OpTypePointer Function %u32vec2
  376. %u8arr = OpTypeArray %u8 %u32_256
  377. %u8arr_ptr_uniform_constant = OpTypePointer UniformConstant %u8arr
  378. %u8arr_uniform_constant = OpVariable %u8arr_ptr_uniform_constant UniformConstant
  379. %u8_ptr_uniform_constant = OpTypePointer UniformConstant %u8
  380. %u8_ptr_generic = OpTypePointer Generic %u8
  381. %u8_ptr_input = OpTypePointer Input %u8
  382. %main = OpFunction %void None %func
  383. %main_entry = OpLabel
  384. )";
  385. ss << body;
  386. ss << R"(
  387. OpReturn
  388. OpFunctionEnd)";
  389. return ss.str();
  390. }
  391. TEST_P(ValidateGlslStd450SqrtLike, Success) {
  392. const std::string ext_inst_name = GetParam();
  393. std::ostringstream ss;
  394. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
  395. ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  396. << " %f32vec2_01\n";
  397. ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n";
  398. CompileSuccessfully(GenerateShaderCode(ss.str()));
  399. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  400. }
  401. TEST_P(ValidateGlslStd450SqrtLike, IntResultType) {
  402. const std::string ext_inst_name = GetParam();
  403. const std::string body =
  404. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
  405. CompileSuccessfully(GenerateShaderCode(body));
  406. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  407. EXPECT_THAT(getDiagnosticString(),
  408. HasSubstr("GLSL.std.450 " + ext_inst_name +
  409. ": expected Result Type to be a float scalar "
  410. "or vector type"));
  411. }
  412. TEST_P(ValidateGlslStd450SqrtLike, IntOperand) {
  413. const std::string ext_inst_name = GetParam();
  414. const std::string body =
  415. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
  416. CompileSuccessfully(GenerateShaderCode(body));
  417. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  418. EXPECT_THAT(getDiagnosticString(),
  419. HasSubstr("GLSL.std.450 " + ext_inst_name +
  420. ": expected types of all operands to be equal to "
  421. "Result Type"));
  422. }
  423. INSTANTIATE_TEST_SUITE_P(AllSqrtLike, ValidateGlslStd450SqrtLike,
  424. ::testing::ValuesIn(std::vector<std::string>{
  425. "Round",
  426. "RoundEven",
  427. "FAbs",
  428. "Trunc",
  429. "FSign",
  430. "Floor",
  431. "Ceil",
  432. "Fract",
  433. "Sqrt",
  434. "InverseSqrt",
  435. "Normalize",
  436. }));
  437. TEST_P(ValidateGlslStd450FMinLike, Success) {
  438. const std::string ext_inst_name = GetParam();
  439. std::ostringstream ss;
  440. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  441. << " %f32_0 %f32_1\n";
  442. ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  443. << " %f32vec2_01 %f32vec2_12\n";
  444. ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
  445. << " %f64_0 %f64_0\n";
  446. CompileSuccessfully(GenerateShaderCode(ss.str()));
  447. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  448. }
  449. TEST_P(ValidateGlslStd450FMinLike, IntResultType) {
  450. const std::string ext_inst_name = GetParam();
  451. const std::string body =
  452. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n";
  453. CompileSuccessfully(GenerateShaderCode(body));
  454. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  455. EXPECT_THAT(getDiagnosticString(),
  456. HasSubstr("GLSL.std.450 " + ext_inst_name +
  457. ": expected Result Type to be a float scalar "
  458. "or vector type"));
  459. }
  460. TEST_P(ValidateGlslStd450FMinLike, IntOperand1) {
  461. const std::string ext_inst_name = GetParam();
  462. const std::string body =
  463. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
  464. CompileSuccessfully(GenerateShaderCode(body));
  465. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  466. EXPECT_THAT(getDiagnosticString(),
  467. HasSubstr("GLSL.std.450 " + ext_inst_name +
  468. ": expected types of all operands to be equal to "
  469. "Result Type"));
  470. }
  471. TEST_P(ValidateGlslStd450FMinLike, IntOperand2) {
  472. const std::string ext_inst_name = GetParam();
  473. const std::string body =
  474. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
  475. CompileSuccessfully(GenerateShaderCode(body));
  476. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  477. EXPECT_THAT(getDiagnosticString(),
  478. HasSubstr("GLSL.std.450 " + ext_inst_name +
  479. ": expected types of all operands to be equal to "
  480. "Result Type"));
  481. }
  482. INSTANTIATE_TEST_SUITE_P(AllFMinLike, ValidateGlslStd450FMinLike,
  483. ::testing::ValuesIn(std::vector<std::string>{
  484. "FMin",
  485. "FMax",
  486. "Step",
  487. "Reflect",
  488. "NMin",
  489. "NMax",
  490. }));
  491. TEST_P(ValidateGlslStd450FClampLike, Success) {
  492. const std::string ext_inst_name = GetParam();
  493. std::ostringstream ss;
  494. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  495. << " %f32_0 %f32_1 %f32_2\n";
  496. ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  497. << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n";
  498. ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
  499. << " %f64_0 %f64_0 %f64_1\n";
  500. CompileSuccessfully(GenerateShaderCode(ss.str()));
  501. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  502. }
  503. TEST_P(ValidateGlslStd450FClampLike, IntResultType) {
  504. const std::string ext_inst_name = GetParam();
  505. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  506. " %f32_0 %f32_1 %f32_2\n";
  507. CompileSuccessfully(GenerateShaderCode(body));
  508. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  509. EXPECT_THAT(getDiagnosticString(),
  510. HasSubstr("GLSL.std.450 " + ext_inst_name +
  511. ": expected Result Type to be a float scalar "
  512. "or vector type"));
  513. }
  514. TEST_P(ValidateGlslStd450FClampLike, IntOperand1) {
  515. const std::string ext_inst_name = GetParam();
  516. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  517. " %u32_0 %f32_0 %f32_1\n";
  518. CompileSuccessfully(GenerateShaderCode(body));
  519. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  520. EXPECT_THAT(getDiagnosticString(),
  521. HasSubstr("GLSL.std.450 " + ext_inst_name +
  522. ": expected types of all operands to be equal to "
  523. "Result Type"));
  524. }
  525. TEST_P(ValidateGlslStd450FClampLike, IntOperand2) {
  526. const std::string ext_inst_name = GetParam();
  527. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  528. " %f32_0 %u32_0 %f32_1\n";
  529. CompileSuccessfully(GenerateShaderCode(body));
  530. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  531. EXPECT_THAT(getDiagnosticString(),
  532. HasSubstr("GLSL.std.450 " + ext_inst_name +
  533. ": expected types of all operands to be equal to "
  534. "Result Type"));
  535. }
  536. TEST_P(ValidateGlslStd450FClampLike, IntOperand3) {
  537. const std::string ext_inst_name = GetParam();
  538. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  539. " %f32_1 %f32_0 %u32_2\n";
  540. CompileSuccessfully(GenerateShaderCode(body));
  541. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  542. EXPECT_THAT(getDiagnosticString(),
  543. HasSubstr("GLSL.std.450 " + ext_inst_name +
  544. ": expected types of all operands to be equal to "
  545. "Result Type"));
  546. }
  547. INSTANTIATE_TEST_SUITE_P(AllFClampLike, ValidateGlslStd450FClampLike,
  548. ::testing::ValuesIn(std::vector<std::string>{
  549. "FClamp",
  550. "FMix",
  551. "SmoothStep",
  552. "Fma",
  553. "FaceForward",
  554. "NClamp",
  555. }));
  556. TEST_P(ValidateGlslStd450SAbsLike, Success) {
  557. const std::string ext_inst_name = GetParam();
  558. std::ostringstream ss;
  559. ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name << " %u32_1\n";
  560. ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name << " %s32_1\n";
  561. ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
  562. ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %s32_1\n";
  563. ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
  564. << " %s32vec2_01\n";
  565. ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  566. << " %u32vec2_01\n";
  567. ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  568. << " %s32vec2_01\n";
  569. ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
  570. << " %u32vec2_01\n";
  571. CompileSuccessfully(GenerateShaderCode(ss.str()));
  572. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  573. }
  574. TEST_P(ValidateGlslStd450SAbsLike, FloatResultType) {
  575. const std::string ext_inst_name = GetParam();
  576. const std::string body =
  577. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
  578. CompileSuccessfully(GenerateShaderCode(body));
  579. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  580. EXPECT_THAT(getDiagnosticString(),
  581. HasSubstr("GLSL.std.450 " + ext_inst_name +
  582. ": expected Result Type to be an int scalar "
  583. "or vector type"));
  584. }
  585. TEST_P(ValidateGlslStd450SAbsLike, FloatOperand) {
  586. const std::string ext_inst_name = GetParam();
  587. const std::string body =
  588. "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %f32_0\n";
  589. CompileSuccessfully(GenerateShaderCode(body));
  590. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  591. EXPECT_THAT(getDiagnosticString(),
  592. HasSubstr("GLSL.std.450 " + ext_inst_name +
  593. ": expected all operands to be int scalars or "
  594. "vectors"));
  595. }
  596. TEST_P(ValidateGlslStd450SAbsLike, WrongDimOperand) {
  597. const std::string ext_inst_name = GetParam();
  598. const std::string body =
  599. "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %s32vec2_01\n";
  600. CompileSuccessfully(GenerateShaderCode(body));
  601. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  602. EXPECT_THAT(getDiagnosticString(),
  603. HasSubstr("GLSL.std.450 " + ext_inst_name +
  604. ": expected all operands to have the same dimension as "
  605. "Result Type"));
  606. }
  607. TEST_P(ValidateGlslStd450SAbsLike, WrongBitWidthOperand) {
  608. const std::string ext_inst_name = GetParam();
  609. const std::string body =
  610. "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s32_0\n";
  611. CompileSuccessfully(GenerateShaderCode(body));
  612. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  613. EXPECT_THAT(getDiagnosticString(),
  614. HasSubstr("GLSL.std.450 " + ext_inst_name +
  615. ": expected all operands to have the same bit width as "
  616. "Result Type"));
  617. }
  618. TEST_P(ValidateGlslStd450SAbsLike, TypelessOperand) {
  619. const std::string ext_inst_name = GetParam();
  620. const std::string body =
  621. "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %main_entry\n";
  622. CompileSuccessfully(GenerateShaderCode(body));
  623. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  624. EXPECT_THAT(
  625. getDiagnosticString(),
  626. HasSubstr("GLSL.std.450 " + ext_inst_name +
  627. ": expected all operands to be int scalars or vectors"));
  628. }
  629. INSTANTIATE_TEST_SUITE_P(AllSAbsLike, ValidateGlslStd450SAbsLike,
  630. ::testing::ValuesIn(std::vector<std::string>{
  631. "SAbs",
  632. "SSign",
  633. "FindILsb",
  634. "FindUMsb",
  635. "FindSMsb",
  636. }));
  637. TEST_F(ValidateExtInst, FindUMsbNot32Bit) {
  638. const std::string body = R"(
  639. %val1 = OpExtInst %s64 %extinst FindUMsb %u64_1
  640. )";
  641. CompileSuccessfully(GenerateShaderCode(body));
  642. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  643. EXPECT_THAT(getDiagnosticString(),
  644. HasSubstr("GLSL.std.450 FindUMsb: this instruction is currently "
  645. "limited to 32-bit width components"));
  646. }
  647. TEST_F(ValidateExtInst, FindSMsbNot32Bit) {
  648. const std::string body = R"(
  649. %val1 = OpExtInst %s64 %extinst FindSMsb %u64_1
  650. )";
  651. CompileSuccessfully(GenerateShaderCode(body));
  652. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  653. EXPECT_THAT(getDiagnosticString(),
  654. HasSubstr("GLSL.std.450 FindSMsb: this instruction is currently "
  655. "limited to 32-bit width components"));
  656. }
  657. TEST_P(ValidateGlslStd450UMinLike, Success) {
  658. const std::string ext_inst_name = GetParam();
  659. std::ostringstream ss;
  660. ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name
  661. << " %u32_1 %s32_2\n";
  662. ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name
  663. << " %s32_1 %u32_2\n";
  664. ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
  665. << " %u32_1 %s32_2\n";
  666. ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
  667. << " %s32_1 %u32_2\n";
  668. ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
  669. << " %s32vec2_01 %u32vec2_01\n";
  670. ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  671. << " %u32vec2_01 %s32vec2_01\n";
  672. ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  673. << " %s32vec2_01 %u32vec2_01\n";
  674. ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
  675. << " %u32vec2_01 %s32vec2_01\n";
  676. ss << "%val9 = OpExtInst %s64 %extinst " << ext_inst_name
  677. << " %u64_1 %s64_0\n";
  678. CompileSuccessfully(GenerateShaderCode(ss.str()));
  679. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  680. }
  681. TEST_P(ValidateGlslStd450UMinLike, FloatResultType) {
  682. const std::string ext_inst_name = GetParam();
  683. const std::string body =
  684. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
  685. CompileSuccessfully(GenerateShaderCode(body));
  686. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  687. EXPECT_THAT(getDiagnosticString(),
  688. HasSubstr("GLSL.std.450 " + ext_inst_name +
  689. ": expected Result Type to be an int scalar "
  690. "or vector type"));
  691. }
  692. TEST_P(ValidateGlslStd450UMinLike, FloatOperand1) {
  693. const std::string ext_inst_name = GetParam();
  694. const std::string body =
  695. "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
  696. CompileSuccessfully(GenerateShaderCode(body));
  697. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  698. EXPECT_THAT(getDiagnosticString(),
  699. HasSubstr("GLSL.std.450 " + ext_inst_name +
  700. ": expected all operands to be int scalars or "
  701. "vectors"));
  702. }
  703. TEST_P(ValidateGlslStd450UMinLike, FloatOperand2) {
  704. const std::string ext_inst_name = GetParam();
  705. const std::string body =
  706. "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
  707. CompileSuccessfully(GenerateShaderCode(body));
  708. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  709. EXPECT_THAT(getDiagnosticString(),
  710. HasSubstr("GLSL.std.450 " + ext_inst_name +
  711. ": expected all operands to be int scalars or "
  712. "vectors"));
  713. }
  714. TEST_P(ValidateGlslStd450UMinLike, WrongDimOperand1) {
  715. const std::string ext_inst_name = GetParam();
  716. const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
  717. " %s32vec2_01 %s32_0\n";
  718. CompileSuccessfully(GenerateShaderCode(body));
  719. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  720. EXPECT_THAT(getDiagnosticString(),
  721. HasSubstr("GLSL.std.450 " + ext_inst_name +
  722. ": expected all operands to have the same dimension as "
  723. "Result Type"));
  724. }
  725. TEST_P(ValidateGlslStd450UMinLike, WrongDimOperand2) {
  726. const std::string ext_inst_name = GetParam();
  727. const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
  728. " %s32_0 %s32vec2_01\n";
  729. CompileSuccessfully(GenerateShaderCode(body));
  730. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  731. EXPECT_THAT(getDiagnosticString(),
  732. HasSubstr("GLSL.std.450 " + ext_inst_name +
  733. ": expected all operands to have the same dimension as "
  734. "Result Type"));
  735. }
  736. TEST_P(ValidateGlslStd450UMinLike, WrongBitWidthOperand1) {
  737. const std::string ext_inst_name = GetParam();
  738. const std::string body =
  739. "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s32_0 %s64_0\n";
  740. CompileSuccessfully(GenerateShaderCode(body));
  741. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  742. EXPECT_THAT(getDiagnosticString(),
  743. HasSubstr("GLSL.std.450 " + ext_inst_name +
  744. ": expected all operands to have the same bit width as "
  745. "Result Type"));
  746. }
  747. TEST_P(ValidateGlslStd450UMinLike, WrongBitWidthOperand2) {
  748. const std::string ext_inst_name = GetParam();
  749. const std::string body =
  750. "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s64_0 %s32_0\n";
  751. CompileSuccessfully(GenerateShaderCode(body));
  752. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  753. EXPECT_THAT(getDiagnosticString(),
  754. HasSubstr("GLSL.std.450 " + ext_inst_name +
  755. ": expected all operands to have the same bit width as "
  756. "Result Type"));
  757. }
  758. TEST_P(ValidateGlslStd450UMinLike, TypelessOperand) {
  759. const std::string ext_inst_name = GetParam();
  760. const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
  761. " %s64_0 %main_entry\n";
  762. CompileSuccessfully(GenerateShaderCode(body));
  763. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  764. EXPECT_THAT(
  765. getDiagnosticString(),
  766. HasSubstr("GLSL.std.450 " + ext_inst_name +
  767. ": expected all operands to be int scalars or vectors"));
  768. }
  769. INSTANTIATE_TEST_SUITE_P(AllUMinLike, ValidateGlslStd450UMinLike,
  770. ::testing::ValuesIn(std::vector<std::string>{
  771. "UMin",
  772. "SMin",
  773. "UMax",
  774. "SMax",
  775. }));
  776. TEST_P(ValidateGlslStd450UClampLike, Success) {
  777. const std::string ext_inst_name = GetParam();
  778. std::ostringstream ss;
  779. ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name
  780. << " %s32_0 %u32_1 %s32_2\n";
  781. ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name
  782. << " %u32_0 %s32_1 %u32_2\n";
  783. ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
  784. << " %s32_0 %u32_1 %s32_2\n";
  785. ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
  786. << " %u32_0 %s32_1 %u32_2\n";
  787. ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
  788. << " %s32vec2_01 %u32vec2_01 %u32vec2_12\n";
  789. ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  790. << " %u32vec2_01 %s32vec2_01 %s32vec2_12\n";
  791. ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  792. << " %s32vec2_01 %u32vec2_01 %u32vec2_12\n";
  793. ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
  794. << " %u32vec2_01 %s32vec2_01 %s32vec2_12\n";
  795. ss << "%val9 = OpExtInst %s64 %extinst " << ext_inst_name
  796. << " %u64_1 %s64_0 %s64_1\n";
  797. CompileSuccessfully(GenerateShaderCode(ss.str()));
  798. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  799. }
  800. TEST_P(ValidateGlslStd450UClampLike, FloatResultType) {
  801. const std::string ext_inst_name = GetParam();
  802. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  803. " %u32_0 %u32_0 %u32_1\n";
  804. CompileSuccessfully(GenerateShaderCode(body));
  805. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  806. EXPECT_THAT(getDiagnosticString(),
  807. HasSubstr("GLSL.std.450 " + ext_inst_name +
  808. ": expected Result Type to be an int scalar "
  809. "or vector type"));
  810. }
  811. TEST_P(ValidateGlslStd450UClampLike, FloatOperand1) {
  812. const std::string ext_inst_name = GetParam();
  813. const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
  814. " %f32_0 %u32_0 %u32_1\n";
  815. CompileSuccessfully(GenerateShaderCode(body));
  816. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  817. EXPECT_THAT(getDiagnosticString(),
  818. HasSubstr("GLSL.std.450 " + ext_inst_name +
  819. ": expected all operands to be int scalars or "
  820. "vectors"));
  821. }
  822. TEST_P(ValidateGlslStd450UClampLike, FloatOperand2) {
  823. const std::string ext_inst_name = GetParam();
  824. const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
  825. " %u32_0 %f32_0 %u32_1\n";
  826. CompileSuccessfully(GenerateShaderCode(body));
  827. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  828. EXPECT_THAT(getDiagnosticString(),
  829. HasSubstr("GLSL.std.450 " + ext_inst_name +
  830. ": expected all operands to be int scalars or "
  831. "vectors"));
  832. }
  833. TEST_P(ValidateGlslStd450UClampLike, FloatOperand3) {
  834. const std::string ext_inst_name = GetParam();
  835. const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
  836. " %u32_0 %u32_0 %f32_1\n";
  837. CompileSuccessfully(GenerateShaderCode(body));
  838. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  839. EXPECT_THAT(getDiagnosticString(),
  840. HasSubstr("GLSL.std.450 " + ext_inst_name +
  841. ": expected all operands to be int scalars or "
  842. "vectors"));
  843. }
  844. TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand1) {
  845. const std::string ext_inst_name = GetParam();
  846. const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
  847. " %s32vec2_01 %s32_0 %u32_1\n";
  848. CompileSuccessfully(GenerateShaderCode(body));
  849. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  850. EXPECT_THAT(getDiagnosticString(),
  851. HasSubstr("GLSL.std.450 " + ext_inst_name +
  852. ": expected all operands to have the same dimension as "
  853. "Result Type"));
  854. }
  855. TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand2) {
  856. const std::string ext_inst_name = GetParam();
  857. const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
  858. " %s32_0 %s32vec2_01 %u32_1\n";
  859. CompileSuccessfully(GenerateShaderCode(body));
  860. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  861. EXPECT_THAT(getDiagnosticString(),
  862. HasSubstr("GLSL.std.450 " + ext_inst_name +
  863. ": expected all operands to have the same dimension as "
  864. "Result Type"));
  865. }
  866. TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand3) {
  867. const std::string ext_inst_name = GetParam();
  868. const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
  869. " %s32_0 %u32_1 %s32vec2_01\n";
  870. CompileSuccessfully(GenerateShaderCode(body));
  871. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  872. EXPECT_THAT(getDiagnosticString(),
  873. HasSubstr("GLSL.std.450 " + ext_inst_name +
  874. ": expected all operands to have the same dimension as "
  875. "Result Type"));
  876. }
  877. TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand1) {
  878. const std::string ext_inst_name = GetParam();
  879. const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
  880. " %s32_0 %s64_0 %s64_1\n";
  881. CompileSuccessfully(GenerateShaderCode(body));
  882. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  883. EXPECT_THAT(getDiagnosticString(),
  884. HasSubstr("GLSL.std.450 " + ext_inst_name +
  885. ": expected all operands to have the same bit width as "
  886. "Result Type"));
  887. }
  888. TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand2) {
  889. const std::string ext_inst_name = GetParam();
  890. const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
  891. " %s64_0 %s32_0 %s64_1\n";
  892. CompileSuccessfully(GenerateShaderCode(body));
  893. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  894. EXPECT_THAT(getDiagnosticString(),
  895. HasSubstr("GLSL.std.450 " + ext_inst_name +
  896. ": expected all operands to have the same bit width as "
  897. "Result Type"));
  898. }
  899. TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand3) {
  900. const std::string ext_inst_name = GetParam();
  901. const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
  902. " %s64_0 %s64_0 %s32_1\n";
  903. CompileSuccessfully(GenerateShaderCode(body));
  904. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  905. EXPECT_THAT(getDiagnosticString(),
  906. HasSubstr("GLSL.std.450 " + ext_inst_name +
  907. ": expected all operands to have the same bit width as "
  908. "Result Type"));
  909. }
  910. TEST_P(ValidateGlslStd450UClampLike, TypelessOperand) {
  911. const std::string ext_inst_name = GetParam();
  912. const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
  913. " %main_entry %s64_0 %s64_0\n";
  914. CompileSuccessfully(GenerateShaderCode(body));
  915. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  916. EXPECT_THAT(
  917. getDiagnosticString(),
  918. HasSubstr("GLSL.std.450 " + ext_inst_name +
  919. ": expected all operands to be int scalars or vectors"));
  920. }
  921. INSTANTIATE_TEST_SUITE_P(AllUClampLike, ValidateGlslStd450UClampLike,
  922. ::testing::ValuesIn(std::vector<std::string>{
  923. "UClamp",
  924. "SClamp",
  925. }));
  926. TEST_P(ValidateGlslStd450SinLike, Success) {
  927. const std::string ext_inst_name = GetParam();
  928. std::ostringstream ss;
  929. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
  930. ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  931. << " %f32vec2_01\n";
  932. CompileSuccessfully(GenerateShaderCode(ss.str()));
  933. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  934. }
  935. TEST_P(ValidateGlslStd450SinLike, IntResultType) {
  936. const std::string ext_inst_name = GetParam();
  937. const std::string body =
  938. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
  939. CompileSuccessfully(GenerateShaderCode(body));
  940. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  941. EXPECT_THAT(getDiagnosticString(),
  942. HasSubstr("GLSL.std.450 " + ext_inst_name +
  943. ": expected Result Type to be a 16 or 32-bit scalar "
  944. "or vector float type"));
  945. }
  946. TEST_P(ValidateGlslStd450SinLike, F64ResultType) {
  947. const std::string ext_inst_name = GetParam();
  948. const std::string body =
  949. "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32_0\n";
  950. CompileSuccessfully(GenerateShaderCode(body));
  951. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  952. EXPECT_THAT(getDiagnosticString(),
  953. HasSubstr("GLSL.std.450 " + ext_inst_name +
  954. ": expected Result Type to be a 16 or 32-bit scalar "
  955. "or vector float type"));
  956. }
  957. TEST_P(ValidateGlslStd450SinLike, IntOperand) {
  958. const std::string ext_inst_name = GetParam();
  959. const std::string body =
  960. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
  961. CompileSuccessfully(GenerateShaderCode(body));
  962. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  963. EXPECT_THAT(getDiagnosticString(),
  964. HasSubstr("GLSL.std.450 " + ext_inst_name +
  965. ": expected types of all operands to be equal to "
  966. "Result Type"));
  967. }
  968. INSTANTIATE_TEST_SUITE_P(AllSinLike, ValidateGlslStd450SinLike,
  969. ::testing::ValuesIn(std::vector<std::string>{
  970. "Radians",
  971. "Degrees",
  972. "Sin",
  973. "Cos",
  974. "Tan",
  975. "Asin",
  976. "Acos",
  977. "Atan",
  978. "Sinh",
  979. "Cosh",
  980. "Tanh",
  981. "Asinh",
  982. "Acosh",
  983. "Atanh",
  984. "Exp",
  985. "Exp2",
  986. "Log",
  987. "Log2",
  988. }));
  989. TEST_P(ValidateGlslStd450PowLike, Success) {
  990. const std::string ext_inst_name = GetParam();
  991. std::ostringstream ss;
  992. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  993. << " %f32_1 %f32_1\n";
  994. ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  995. << " %f32vec2_01 %f32vec2_12\n";
  996. CompileSuccessfully(GenerateShaderCode(ss.str()));
  997. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  998. }
  999. TEST_P(ValidateGlslStd450PowLike, IntResultType) {
  1000. const std::string ext_inst_name = GetParam();
  1001. const std::string body =
  1002. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_1 %f32_0\n";
  1003. CompileSuccessfully(GenerateShaderCode(body));
  1004. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1005. EXPECT_THAT(getDiagnosticString(),
  1006. HasSubstr("GLSL.std.450 " + ext_inst_name +
  1007. ": expected Result Type to be a 16 or 32-bit scalar "
  1008. "or vector float type"));
  1009. }
  1010. TEST_P(ValidateGlslStd450PowLike, F64ResultType) {
  1011. const std::string ext_inst_name = GetParam();
  1012. const std::string body =
  1013. "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32_1 %f32_0\n";
  1014. CompileSuccessfully(GenerateShaderCode(body));
  1015. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1016. EXPECT_THAT(getDiagnosticString(),
  1017. HasSubstr("GLSL.std.450 " + ext_inst_name +
  1018. ": expected Result Type to be a 16 or 32-bit scalar "
  1019. "or vector float type"));
  1020. }
  1021. TEST_P(ValidateGlslStd450PowLike, IntOperand1) {
  1022. const std::string ext_inst_name = GetParam();
  1023. const std::string body =
  1024. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
  1025. CompileSuccessfully(GenerateShaderCode(body));
  1026. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1027. EXPECT_THAT(getDiagnosticString(),
  1028. HasSubstr("GLSL.std.450 " + ext_inst_name +
  1029. ": expected types of all operands to be equal to "
  1030. "Result Type"));
  1031. }
  1032. TEST_P(ValidateGlslStd450PowLike, IntOperand2) {
  1033. const std::string ext_inst_name = GetParam();
  1034. const std::string body =
  1035. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
  1036. CompileSuccessfully(GenerateShaderCode(body));
  1037. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1038. EXPECT_THAT(getDiagnosticString(),
  1039. HasSubstr("GLSL.std.450 " + ext_inst_name +
  1040. ": expected types of all operands to be equal to "
  1041. "Result Type"));
  1042. }
  1043. INSTANTIATE_TEST_SUITE_P(AllPowLike, ValidateGlslStd450PowLike,
  1044. ::testing::ValuesIn(std::vector<std::string>{
  1045. "Atan2",
  1046. "Pow",
  1047. }));
  1048. TEST_F(ValidateExtInst, GlslStd450DeterminantSuccess) {
  1049. const std::string body = R"(
  1050. %val1 = OpExtInst %f32 %extinst Determinant %f32mat22_1212
  1051. )";
  1052. CompileSuccessfully(GenerateShaderCode(body));
  1053. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1054. }
  1055. TEST_F(ValidateExtInst, GlslStd450DeterminantIncompatibleResultType) {
  1056. const std::string body = R"(
  1057. %val1 = OpExtInst %f64 %extinst Determinant %f32mat22_1212
  1058. )";
  1059. CompileSuccessfully(GenerateShaderCode(body));
  1060. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1061. EXPECT_THAT(getDiagnosticString(),
  1062. HasSubstr("GLSL.std.450 Determinant: "
  1063. "expected operand X component type to be equal to "
  1064. "Result Type"));
  1065. }
  1066. TEST_F(ValidateExtInst, GlslStd450DeterminantNotMatrix) {
  1067. const std::string body = R"(
  1068. %val1 = OpExtInst %f32 %extinst Determinant %f32_1
  1069. )";
  1070. CompileSuccessfully(GenerateShaderCode(body));
  1071. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1072. EXPECT_THAT(getDiagnosticString(),
  1073. HasSubstr("GLSL.std.450 Determinant: "
  1074. "expected operand X to be a square matrix"));
  1075. }
  1076. TEST_F(ValidateExtInst, GlslStd450DeterminantMatrixNotSquare) {
  1077. const std::string body = R"(
  1078. %val1 = OpExtInst %f32 %extinst Determinant %f32mat23_121212
  1079. )";
  1080. CompileSuccessfully(GenerateShaderCode(body));
  1081. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1082. EXPECT_THAT(getDiagnosticString(),
  1083. HasSubstr("GLSL.std.450 Determinant: "
  1084. "expected operand X to be a square matrix"));
  1085. }
  1086. TEST_F(ValidateExtInst, GlslStd450MatrixInverseSuccess) {
  1087. const std::string body = R"(
  1088. %val1 = OpExtInst %f32mat22 %extinst MatrixInverse %f32mat22_1212
  1089. )";
  1090. CompileSuccessfully(GenerateShaderCode(body));
  1091. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1092. }
  1093. TEST_F(ValidateExtInst, GlslStd450MatrixInverseIncompatibleResultType) {
  1094. const std::string body = R"(
  1095. %val1 = OpExtInst %f32mat33 %extinst MatrixInverse %f32mat22_1212
  1096. )";
  1097. CompileSuccessfully(GenerateShaderCode(body));
  1098. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1099. EXPECT_THAT(getDiagnosticString(),
  1100. HasSubstr("GLSL.std.450 MatrixInverse: "
  1101. "expected operand X type to be equal to "
  1102. "Result Type"));
  1103. }
  1104. TEST_F(ValidateExtInst, GlslStd450MatrixInverseNotMatrix) {
  1105. const std::string body = R"(
  1106. %val1 = OpExtInst %f32 %extinst MatrixInverse %f32mat22_1212
  1107. )";
  1108. CompileSuccessfully(GenerateShaderCode(body));
  1109. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1110. EXPECT_THAT(getDiagnosticString(),
  1111. HasSubstr("GLSL.std.450 MatrixInverse: "
  1112. "expected Result Type to be a square matrix"));
  1113. }
  1114. TEST_F(ValidateExtInst, GlslStd450MatrixInverseMatrixNotSquare) {
  1115. const std::string body = R"(
  1116. %val1 = OpExtInst %f32mat23 %extinst MatrixInverse %f32mat23_121212
  1117. )";
  1118. CompileSuccessfully(GenerateShaderCode(body));
  1119. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1120. EXPECT_THAT(getDiagnosticString(),
  1121. HasSubstr("GLSL.std.450 MatrixInverse: "
  1122. "expected Result Type to be a square matrix"));
  1123. }
  1124. TEST_F(ValidateExtInst, GlslStd450ModfSuccess) {
  1125. const std::string body = R"(
  1126. %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32_output
  1127. %val2 = OpExtInst %f32vec2 %extinst Modf %f32vec2_01 %f32vec2_output
  1128. )";
  1129. CompileSuccessfully(GenerateShaderCode(body));
  1130. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1131. }
  1132. TEST_F(ValidateExtInst, GlslStd450ModfIntResultType) {
  1133. const std::string body = R"(
  1134. %val1 = OpExtInst %u32 %extinst Modf %f32_h %f32_output
  1135. )";
  1136. CompileSuccessfully(GenerateShaderCode(body));
  1137. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1138. EXPECT_THAT(getDiagnosticString(),
  1139. HasSubstr("GLSL.std.450 Modf: "
  1140. "expected Result Type to be a scalar or vector "
  1141. "float type"));
  1142. }
  1143. TEST_F(ValidateExtInst, GlslStd450ModfXNotOfResultType) {
  1144. const std::string body = R"(
  1145. %val1 = OpExtInst %f32 %extinst Modf %f64_0 %f32_output
  1146. )";
  1147. CompileSuccessfully(GenerateShaderCode(body));
  1148. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1149. EXPECT_THAT(getDiagnosticString(),
  1150. HasSubstr("GLSL.std.450 Modf: "
  1151. "expected operand X type to be equal to Result Type"));
  1152. }
  1153. TEST_F(ValidateExtInst, GlslStd450ModfINotPointer) {
  1154. const std::string body = R"(
  1155. %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32_1
  1156. )";
  1157. CompileSuccessfully(GenerateShaderCode(body));
  1158. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1159. EXPECT_THAT(getDiagnosticString(),
  1160. HasSubstr("GLSL.std.450 Modf: "
  1161. "expected operand I to be a pointer"));
  1162. }
  1163. TEST_F(ValidateExtInst, GlslStd450ModfIDataNotOfResultType) {
  1164. const std::string body = R"(
  1165. %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32vec2_output
  1166. )";
  1167. CompileSuccessfully(GenerateShaderCode(body));
  1168. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1169. EXPECT_THAT(getDiagnosticString(),
  1170. HasSubstr("GLSL.std.450 Modf: "
  1171. "expected operand I data type to be equal to "
  1172. "Result Type"));
  1173. }
  1174. TEST_F(ValidateExtInst, GlslStd450ModfStructSuccess) {
  1175. const std::string body = R"(
  1176. %val1 = OpExtInst %struct_f32_f32 %extinst ModfStruct %f32_h
  1177. %val2 = OpExtInst %struct_f32vec2_f32vec2 %extinst ModfStruct %f32vec2_01
  1178. )";
  1179. CompileSuccessfully(GenerateShaderCode(body));
  1180. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1181. }
  1182. TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeNotStruct) {
  1183. const std::string body = R"(
  1184. %val1 = OpExtInst %f32 %extinst ModfStruct %f32_h
  1185. )";
  1186. CompileSuccessfully(GenerateShaderCode(body));
  1187. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1188. EXPECT_THAT(getDiagnosticString(),
  1189. HasSubstr("GLSL.std.450 ModfStruct: "
  1190. "expected Result Type to be a struct with two "
  1191. "identical scalar or vector float type members"));
  1192. }
  1193. TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructWrongSize) {
  1194. const std::string body = R"(
  1195. %val1 = OpExtInst %struct_f32_f32_f32 %extinst ModfStruct %f32_h
  1196. )";
  1197. CompileSuccessfully(GenerateShaderCode(body));
  1198. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1199. EXPECT_THAT(getDiagnosticString(),
  1200. HasSubstr("GLSL.std.450 ModfStruct: "
  1201. "expected Result Type to be a struct with two "
  1202. "identical scalar or vector float type members"));
  1203. }
  1204. TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructWrongFirstMember) {
  1205. const std::string body = R"(
  1206. %val1 = OpExtInst %struct_u32_f32 %extinst ModfStruct %f32_h
  1207. )";
  1208. CompileSuccessfully(GenerateShaderCode(body));
  1209. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1210. EXPECT_THAT(getDiagnosticString(),
  1211. HasSubstr("GLSL.std.450 ModfStruct: "
  1212. "expected Result Type to be a struct with two "
  1213. "identical scalar or vector float type members"));
  1214. }
  1215. TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructMembersNotEqual) {
  1216. const std::string body = R"(
  1217. %val1 = OpExtInst %struct_f32_f64 %extinst ModfStruct %f32_h
  1218. )";
  1219. CompileSuccessfully(GenerateShaderCode(body));
  1220. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1221. EXPECT_THAT(getDiagnosticString(),
  1222. HasSubstr("GLSL.std.450 ModfStruct: "
  1223. "expected Result Type to be a struct with two "
  1224. "identical scalar or vector float type members"));
  1225. }
  1226. TEST_F(ValidateExtInst, GlslStd450ModfStructXWrongType) {
  1227. const std::string body = R"(
  1228. %val1 = OpExtInst %struct_f32_f32 %extinst ModfStruct %f64_0
  1229. )";
  1230. CompileSuccessfully(GenerateShaderCode(body));
  1231. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1232. EXPECT_THAT(getDiagnosticString(),
  1233. HasSubstr("GLSL.std.450 ModfStruct: "
  1234. "expected operand X type to be equal to members of "
  1235. "Result Type struct"));
  1236. }
  1237. TEST_F(ValidateExtInst, GlslStd450FrexpSuccess) {
  1238. const std::string body = R"(
  1239. %val1 = OpExtInst %f32 %extinst Frexp %f32_h %u32_output
  1240. %val2 = OpExtInst %f32vec2 %extinst Frexp %f32vec2_01 %u32vec2_output
  1241. )";
  1242. CompileSuccessfully(GenerateShaderCode(body));
  1243. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1244. }
  1245. TEST_F(ValidateExtInst, GlslStd450FrexpIntResultType) {
  1246. const std::string body = R"(
  1247. %val1 = OpExtInst %u32 %extinst Frexp %f32_h %u32_output
  1248. )";
  1249. CompileSuccessfully(GenerateShaderCode(body));
  1250. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1251. EXPECT_THAT(getDiagnosticString(),
  1252. HasSubstr("GLSL.std.450 Frexp: "
  1253. "expected Result Type to be a scalar or vector "
  1254. "float type"));
  1255. }
  1256. TEST_F(ValidateExtInst, GlslStd450FrexpWrongXType) {
  1257. const std::string body = R"(
  1258. %val1 = OpExtInst %f32 %extinst Frexp %u32_1 %u32_output
  1259. )";
  1260. CompileSuccessfully(GenerateShaderCode(body));
  1261. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1262. EXPECT_THAT(getDiagnosticString(),
  1263. HasSubstr("GLSL.std.450 Frexp: "
  1264. "expected operand X type to be equal to Result Type"));
  1265. }
  1266. TEST_F(ValidateExtInst, GlslStd450FrexpExpNotPointer) {
  1267. const std::string body = R"(
  1268. %val1 = OpExtInst %f32 %extinst Frexp %f32_1 %u32_1
  1269. )";
  1270. CompileSuccessfully(GenerateShaderCode(body));
  1271. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1272. EXPECT_THAT(getDiagnosticString(),
  1273. HasSubstr("GLSL.std.450 Frexp: "
  1274. "expected operand Exp to be a pointer"));
  1275. }
  1276. TEST_F(ValidateExtInst, GlslStd450FrexpExpNotInt32Pointer) {
  1277. const std::string body = R"(
  1278. %val1 = OpExtInst %f32 %extinst Frexp %f32_1 %f32_output
  1279. )";
  1280. CompileSuccessfully(GenerateShaderCode(body));
  1281. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1282. EXPECT_THAT(getDiagnosticString(),
  1283. HasSubstr("GLSL.std.450 Frexp: "
  1284. "expected operand Exp data type to be a 32-bit int "
  1285. "scalar or vector type"));
  1286. }
  1287. TEST_F(ValidateExtInst, GlslStd450FrexpExpWrongComponentNumber) {
  1288. const std::string body = R"(
  1289. %val1 = OpExtInst %f32vec2 %extinst Frexp %f32vec2_01 %u32_output
  1290. )";
  1291. CompileSuccessfully(GenerateShaderCode(body));
  1292. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1293. EXPECT_THAT(getDiagnosticString(),
  1294. HasSubstr("GLSL.std.450 Frexp: "
  1295. "expected operand Exp data type to have the same "
  1296. "component number as Result Type"));
  1297. }
  1298. TEST_F(ValidateExtInst, GlslStd450LdexpSuccess) {
  1299. const std::string body = R"(
  1300. %val1 = OpExtInst %f32 %extinst Ldexp %f32_h %u32_2
  1301. %val2 = OpExtInst %f32vec2 %extinst Ldexp %f32vec2_01 %u32vec2_12
  1302. %val3 = OpExtInst %f32 %extinst Ldexp %f32_h %u64_1
  1303. )";
  1304. CompileSuccessfully(GenerateShaderCode(body));
  1305. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1306. }
  1307. TEST_F(ValidateExtInst, GlslStd450LdexpIntResultType) {
  1308. const std::string body = R"(
  1309. %val1 = OpExtInst %u32 %extinst Ldexp %f32_h %u32_2
  1310. )";
  1311. CompileSuccessfully(GenerateShaderCode(body));
  1312. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1313. EXPECT_THAT(getDiagnosticString(),
  1314. HasSubstr("GLSL.std.450 Ldexp: "
  1315. "expected Result Type to be a scalar or vector "
  1316. "float type"));
  1317. }
  1318. TEST_F(ValidateExtInst, GlslStd450LdexpWrongXType) {
  1319. const std::string body = R"(
  1320. %val1 = OpExtInst %f32 %extinst Ldexp %u32_1 %u32_2
  1321. )";
  1322. CompileSuccessfully(GenerateShaderCode(body));
  1323. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1324. EXPECT_THAT(getDiagnosticString(),
  1325. HasSubstr("GLSL.std.450 Ldexp: "
  1326. "expected operand X type to be equal to Result Type"));
  1327. }
  1328. TEST_F(ValidateExtInst, GlslStd450LdexpFloatExp) {
  1329. const std::string body = R"(
  1330. %val1 = OpExtInst %f32 %extinst Ldexp %f32_1 %f32_2
  1331. )";
  1332. CompileSuccessfully(GenerateShaderCode(body));
  1333. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1334. EXPECT_THAT(getDiagnosticString(),
  1335. HasSubstr("GLSL.std.450 Ldexp: "
  1336. "expected operand Exp to be a 32-bit int scalar "
  1337. "or vector type"));
  1338. }
  1339. TEST_F(ValidateExtInst, GlslStd450LdexpExpWrongSize) {
  1340. const std::string body = R"(
  1341. %val1 = OpExtInst %f32vec2 %extinst Ldexp %f32vec2_12 %u32_2
  1342. )";
  1343. CompileSuccessfully(GenerateShaderCode(body));
  1344. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1345. EXPECT_THAT(getDiagnosticString(),
  1346. HasSubstr("GLSL.std.450 Ldexp: "
  1347. "expected operand Exp to have the same component "
  1348. "number as Result Type"));
  1349. }
  1350. TEST_F(ValidateExtInst, GlslStd450LdexpExpNoType) {
  1351. const std::string body = R"(
  1352. %val1 = OpExtInst %f32 %extinst Ldexp %f32_1 %main_entry
  1353. )";
  1354. CompileSuccessfully(GenerateShaderCode(body));
  1355. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1356. EXPECT_THAT(getDiagnosticString(),
  1357. HasSubstr("GLSL.std.450 Ldexp: "
  1358. "expected operand Exp to be a 32-bit int scalar "
  1359. "or vector type"));
  1360. }
  1361. TEST_F(ValidateExtInst, GlslStd450FrexpStructSuccess) {
  1362. const std::string body = R"(
  1363. %val1 = OpExtInst %struct_f32_u32 %extinst FrexpStruct %f32_h
  1364. %val2 = OpExtInst %struct_f32vec2_u32vec2 %extinst FrexpStruct %f32vec2_01
  1365. )";
  1366. CompileSuccessfully(GenerateShaderCode(body));
  1367. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1368. }
  1369. TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeNotStruct) {
  1370. const std::string body = R"(
  1371. %val1 = OpExtInst %f32 %extinst FrexpStruct %f32_h
  1372. )";
  1373. CompileSuccessfully(GenerateShaderCode(body));
  1374. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1375. EXPECT_THAT(getDiagnosticString(),
  1376. HasSubstr("GLSL.std.450 FrexpStruct: "
  1377. "expected Result Type to be a struct with two members, "
  1378. "first member a float scalar or vector, second member "
  1379. "a 32-bit int scalar or vector with the same number of "
  1380. "components as the first member"));
  1381. }
  1382. TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongSize) {
  1383. const std::string body = R"(
  1384. %val1 = OpExtInst %struct_f32_u32_f32 %extinst FrexpStruct %f32_h
  1385. )";
  1386. CompileSuccessfully(GenerateShaderCode(body));
  1387. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1388. EXPECT_THAT(getDiagnosticString(),
  1389. HasSubstr("GLSL.std.450 FrexpStruct: "
  1390. "expected Result Type to be a struct with two members, "
  1391. "first member a float scalar or vector, second member "
  1392. "a 32-bit int scalar or vector with the same number of "
  1393. "components as the first member"));
  1394. }
  1395. TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongMember1) {
  1396. const std::string body = R"(
  1397. %val1 = OpExtInst %struct_u32_u32 %extinst FrexpStruct %f32_h
  1398. )";
  1399. CompileSuccessfully(GenerateShaderCode(body));
  1400. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1401. EXPECT_THAT(getDiagnosticString(),
  1402. HasSubstr("GLSL.std.450 FrexpStruct: "
  1403. "expected Result Type to be a struct with two members, "
  1404. "first member a float scalar or vector, second member "
  1405. "a 32-bit int scalar or vector with the same number of "
  1406. "components as the first member"));
  1407. }
  1408. TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongMember2) {
  1409. const std::string body = R"(
  1410. %val1 = OpExtInst %struct_f32_f32 %extinst FrexpStruct %f32_h
  1411. )";
  1412. CompileSuccessfully(GenerateShaderCode(body));
  1413. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1414. EXPECT_THAT(getDiagnosticString(),
  1415. HasSubstr("GLSL.std.450 FrexpStruct: "
  1416. "expected Result Type to be a struct with two members, "
  1417. "first member a float scalar or vector, second member "
  1418. "a 32-bit int scalar or vector with the same number of "
  1419. "components as the first member"));
  1420. }
  1421. TEST_F(ValidateExtInst, GlslStd450FrexpStructXWrongType) {
  1422. const std::string body = R"(
  1423. %val1 = OpExtInst %struct_f32_u32 %extinst FrexpStruct %f64_0
  1424. )";
  1425. CompileSuccessfully(GenerateShaderCode(body));
  1426. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1427. EXPECT_THAT(getDiagnosticString(),
  1428. HasSubstr("GLSL.std.450 FrexpStruct: "
  1429. "expected operand X type to be equal to the first "
  1430. "member of Result Type struct"));
  1431. }
  1432. TEST_F(ValidateExtInst,
  1433. GlslStd450FrexpStructResultTypeStructRightInt16Member2) {
  1434. const std::string body = R"(
  1435. %val1 = OpExtInst %struct_f16_u16 %extinst FrexpStruct %f16_h
  1436. )";
  1437. const std::string extension = R"(
  1438. OpExtension "SPV_AMD_gpu_shader_int16"
  1439. )";
  1440. CompileSuccessfully(GenerateShaderCode(body, extension));
  1441. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1442. }
  1443. TEST_F(ValidateExtInst,
  1444. GlslStd450FrexpStructResultTypeStructWrongInt16Member2) {
  1445. const std::string body = R"(
  1446. %val1 = OpExtInst %struct_f16_u16 %extinst FrexpStruct %f16_h
  1447. )";
  1448. CompileSuccessfully(GenerateShaderCode(body));
  1449. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1450. EXPECT_THAT(getDiagnosticString(),
  1451. HasSubstr("GLSL.std.450 FrexpStruct: "
  1452. "expected Result Type to be a struct with two members, "
  1453. "first member a float scalar or vector, second member "
  1454. "a 32-bit int scalar or vector with the same number of "
  1455. "components as the first member"));
  1456. }
  1457. TEST_P(ValidateGlslStd450Pack, Success) {
  1458. const std::string ext_inst_name = GetParam();
  1459. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1460. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1461. const uint32_t total_bit_width = num_components * packed_bit_width;
  1462. const std::string vec_str =
  1463. num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
  1464. std::ostringstream body;
  1465. body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
  1466. << ext_inst_name << vec_str;
  1467. body << "%val2 = OpExtInst %s" << total_bit_width << " %extinst "
  1468. << ext_inst_name << vec_str;
  1469. CompileSuccessfully(GenerateShaderCode(body.str()));
  1470. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1471. }
  1472. TEST_P(ValidateGlslStd450Pack, Float32ResultType) {
  1473. const std::string ext_inst_name = GetParam();
  1474. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1475. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1476. const uint32_t total_bit_width = num_components * packed_bit_width;
  1477. const std::string vec_str =
  1478. num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
  1479. std::ostringstream body;
  1480. body << "%val1 = OpExtInst %f" << total_bit_width << " %extinst "
  1481. << ext_inst_name << vec_str;
  1482. std::ostringstream expected;
  1483. expected << "GLSL.std.450 " << ext_inst_name
  1484. << ": expected Result Type to be " << total_bit_width
  1485. << "-bit int scalar type";
  1486. CompileSuccessfully(GenerateShaderCode(body.str()));
  1487. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1488. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
  1489. }
  1490. TEST_P(ValidateGlslStd450Pack, Int16ResultType) {
  1491. const std::string ext_inst_name = GetParam();
  1492. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1493. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1494. const uint32_t total_bit_width = num_components * packed_bit_width;
  1495. const std::string vec_str =
  1496. num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
  1497. std::ostringstream body;
  1498. body << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << vec_str;
  1499. std::ostringstream expected;
  1500. expected << "GLSL.std.450 " << ext_inst_name
  1501. << ": expected Result Type to be " << total_bit_width
  1502. << "-bit int scalar type";
  1503. CompileSuccessfully(GenerateShaderCode(body.str()));
  1504. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1505. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
  1506. }
  1507. TEST_P(ValidateGlslStd450Pack, VNotVector) {
  1508. const std::string ext_inst_name = GetParam();
  1509. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1510. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1511. const uint32_t total_bit_width = num_components * packed_bit_width;
  1512. std::ostringstream body;
  1513. body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
  1514. << ext_inst_name << " %f32_1\n";
  1515. std::ostringstream expected;
  1516. expected << "GLSL.std.450 " << ext_inst_name
  1517. << ": expected operand V to be a 32-bit float vector of size "
  1518. << num_components;
  1519. CompileSuccessfully(GenerateShaderCode(body.str()));
  1520. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1521. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
  1522. }
  1523. TEST_P(ValidateGlslStd450Pack, VNotFloatVector) {
  1524. const std::string ext_inst_name = GetParam();
  1525. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1526. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1527. const uint32_t total_bit_width = num_components * packed_bit_width;
  1528. const std::string vec_str =
  1529. num_components == 2 ? " %u32vec2_01\n" : " %u32vec4_0123\n";
  1530. std::ostringstream body;
  1531. body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
  1532. << ext_inst_name << vec_str;
  1533. std::ostringstream expected;
  1534. expected << "GLSL.std.450 " << ext_inst_name
  1535. << ": expected operand V to be a 32-bit float vector of size "
  1536. << num_components;
  1537. CompileSuccessfully(GenerateShaderCode(body.str()));
  1538. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1539. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
  1540. }
  1541. TEST_P(ValidateGlslStd450Pack, VNotFloat32Vector) {
  1542. const std::string ext_inst_name = GetParam();
  1543. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1544. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1545. const uint32_t total_bit_width = num_components * packed_bit_width;
  1546. const std::string vec_str =
  1547. num_components == 2 ? " %f64vec2_01\n" : " %f64vec4_0123\n";
  1548. std::ostringstream body;
  1549. body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
  1550. << ext_inst_name << vec_str;
  1551. std::ostringstream expected;
  1552. expected << "GLSL.std.450 " << ext_inst_name
  1553. << ": expected operand V to be a 32-bit float vector of size "
  1554. << num_components;
  1555. CompileSuccessfully(GenerateShaderCode(body.str()));
  1556. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1557. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
  1558. }
  1559. TEST_P(ValidateGlslStd450Pack, VWrongSizeVector) {
  1560. const std::string ext_inst_name = GetParam();
  1561. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1562. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1563. const uint32_t total_bit_width = num_components * packed_bit_width;
  1564. const std::string vec_str =
  1565. num_components == 4 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
  1566. std::ostringstream body;
  1567. body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
  1568. << ext_inst_name << vec_str;
  1569. std::ostringstream expected;
  1570. expected << "GLSL.std.450 " << ext_inst_name
  1571. << ": expected operand V to be a 32-bit float vector of size "
  1572. << num_components;
  1573. CompileSuccessfully(GenerateShaderCode(body.str()));
  1574. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1575. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
  1576. }
  1577. INSTANTIATE_TEST_SUITE_P(AllPack, ValidateGlslStd450Pack,
  1578. ::testing::ValuesIn(std::vector<std::string>{
  1579. "PackSnorm4x8",
  1580. "PackUnorm4x8",
  1581. "PackSnorm2x16",
  1582. "PackUnorm2x16",
  1583. "PackHalf2x16",
  1584. }));
  1585. TEST_F(ValidateExtInst, PackDouble2x32Success) {
  1586. const std::string body = R"(
  1587. %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u32vec2_01
  1588. )";
  1589. CompileSuccessfully(GenerateShaderCode(body));
  1590. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1591. }
  1592. TEST_F(ValidateExtInst, PackDouble2x32Float32ResultType) {
  1593. const std::string body = R"(
  1594. %val1 = OpExtInst %f32 %extinst PackDouble2x32 %u32vec2_01
  1595. )";
  1596. CompileSuccessfully(GenerateShaderCode(body));
  1597. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1598. EXPECT_THAT(getDiagnosticString(),
  1599. HasSubstr("GLSL.std.450 PackDouble2x32: expected Result Type to "
  1600. "be 64-bit float scalar type"));
  1601. }
  1602. TEST_F(ValidateExtInst, PackDouble2x32Int64ResultType) {
  1603. const std::string body = R"(
  1604. %val1 = OpExtInst %u64 %extinst PackDouble2x32 %u32vec2_01
  1605. )";
  1606. CompileSuccessfully(GenerateShaderCode(body));
  1607. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1608. EXPECT_THAT(getDiagnosticString(),
  1609. HasSubstr("GLSL.std.450 PackDouble2x32: expected Result Type to "
  1610. "be 64-bit float scalar type"));
  1611. }
  1612. TEST_F(ValidateExtInst, PackDouble2x32VNotVector) {
  1613. const std::string body = R"(
  1614. %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u64_1
  1615. )";
  1616. CompileSuccessfully(GenerateShaderCode(body));
  1617. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1618. EXPECT_THAT(getDiagnosticString(),
  1619. HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
  1620. "a 32-bit int vector of size 2"));
  1621. }
  1622. TEST_F(ValidateExtInst, PackDouble2x32VNotIntVector) {
  1623. const std::string body = R"(
  1624. %val1 = OpExtInst %f64 %extinst PackDouble2x32 %f32vec2_01
  1625. )";
  1626. CompileSuccessfully(GenerateShaderCode(body));
  1627. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1628. EXPECT_THAT(getDiagnosticString(),
  1629. HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
  1630. "a 32-bit int vector of size 2"));
  1631. }
  1632. TEST_F(ValidateExtInst, PackDouble2x32VNotInt32Vector) {
  1633. const std::string body = R"(
  1634. %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u64vec2_01
  1635. )";
  1636. CompileSuccessfully(GenerateShaderCode(body));
  1637. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1638. EXPECT_THAT(getDiagnosticString(),
  1639. HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
  1640. "a 32-bit int vector of size 2"));
  1641. }
  1642. TEST_F(ValidateExtInst, PackDouble2x32VWrongSize) {
  1643. const std::string body = R"(
  1644. %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u32vec4_0123
  1645. )";
  1646. CompileSuccessfully(GenerateShaderCode(body));
  1647. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1648. EXPECT_THAT(getDiagnosticString(),
  1649. HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
  1650. "a 32-bit int vector of size 2"));
  1651. }
  1652. TEST_P(ValidateGlslStd450Unpack, Success) {
  1653. const std::string ext_inst_name = GetParam();
  1654. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1655. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1656. const uint32_t total_bit_width = num_components * packed_bit_width;
  1657. const std::string result_type_str =
  1658. num_components == 2 ? "%f32vec2" : " %f32vec4";
  1659. std::ostringstream body;
  1660. body << "%val1 = OpExtInst " << result_type_str << " %extinst "
  1661. << ext_inst_name << " %u" << total_bit_width << "_1\n";
  1662. body << "%val2 = OpExtInst " << result_type_str << " %extinst "
  1663. << ext_inst_name << " %s" << total_bit_width << "_1\n";
  1664. CompileSuccessfully(GenerateShaderCode(body.str()));
  1665. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1666. }
  1667. TEST_P(ValidateGlslStd450Unpack, ResultTypeNotVector) {
  1668. const std::string ext_inst_name = GetParam();
  1669. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1670. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1671. const uint32_t total_bit_width = num_components * packed_bit_width;
  1672. const std::string result_type_str = "%f32";
  1673. std::ostringstream body;
  1674. body << "%val1 = OpExtInst " << result_type_str << " %extinst "
  1675. << ext_inst_name << " %u" << total_bit_width << "_1\n";
  1676. std::ostringstream expected;
  1677. expected << "GLSL.std.450 " << ext_inst_name
  1678. << ": expected Result Type to be a 32-bit float vector of size "
  1679. << num_components;
  1680. CompileSuccessfully(GenerateShaderCode(body.str()));
  1681. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1682. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
  1683. }
  1684. TEST_P(ValidateGlslStd450Unpack, ResultTypeNotFloatVector) {
  1685. const std::string ext_inst_name = GetParam();
  1686. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1687. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1688. const uint32_t total_bit_width = num_components * packed_bit_width;
  1689. const std::string result_type_str =
  1690. num_components == 2 ? "%u32vec2" : " %u32vec4";
  1691. std::ostringstream body;
  1692. body << "%val1 = OpExtInst " << result_type_str << " %extinst "
  1693. << ext_inst_name << " %u" << total_bit_width << "_1\n";
  1694. std::ostringstream expected;
  1695. expected << "GLSL.std.450 " << ext_inst_name
  1696. << ": expected Result Type to be a 32-bit float vector of size "
  1697. << num_components;
  1698. CompileSuccessfully(GenerateShaderCode(body.str()));
  1699. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1700. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
  1701. }
  1702. TEST_P(ValidateGlslStd450Unpack, ResultTypeNotFloat32Vector) {
  1703. const std::string ext_inst_name = GetParam();
  1704. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1705. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1706. const uint32_t total_bit_width = num_components * packed_bit_width;
  1707. const std::string result_type_str =
  1708. num_components == 2 ? "%f64vec2" : " %f64vec4";
  1709. std::ostringstream body;
  1710. body << "%val1 = OpExtInst " << result_type_str << " %extinst "
  1711. << ext_inst_name << " %u" << total_bit_width << "_1\n";
  1712. std::ostringstream expected;
  1713. expected << "GLSL.std.450 " << ext_inst_name
  1714. << ": expected Result Type to be a 32-bit float vector of size "
  1715. << num_components;
  1716. CompileSuccessfully(GenerateShaderCode(body.str()));
  1717. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1718. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
  1719. }
  1720. TEST_P(ValidateGlslStd450Unpack, ResultTypeWrongSize) {
  1721. const std::string ext_inst_name = GetParam();
  1722. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1723. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1724. const uint32_t total_bit_width = num_components * packed_bit_width;
  1725. const std::string result_type_str =
  1726. num_components == 4 ? "%f32vec2" : " %f32vec4";
  1727. std::ostringstream body;
  1728. body << "%val1 = OpExtInst " << result_type_str << " %extinst "
  1729. << ext_inst_name << " %u" << total_bit_width << "_1\n";
  1730. std::ostringstream expected;
  1731. expected << "GLSL.std.450 " << ext_inst_name
  1732. << ": expected Result Type to be a 32-bit float vector of size "
  1733. << num_components;
  1734. CompileSuccessfully(GenerateShaderCode(body.str()));
  1735. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1736. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
  1737. }
  1738. TEST_P(ValidateGlslStd450Unpack, ResultPNotInt) {
  1739. const std::string ext_inst_name = GetParam();
  1740. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1741. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1742. const uint32_t total_bit_width = num_components * packed_bit_width;
  1743. const std::string result_type_str =
  1744. num_components == 2 ? "%f32vec2" : " %f32vec4";
  1745. std::ostringstream body;
  1746. body << "%val1 = OpExtInst " << result_type_str << " %extinst "
  1747. << ext_inst_name << " %f" << total_bit_width << "_1\n";
  1748. std::ostringstream expected;
  1749. expected << "GLSL.std.450 " << ext_inst_name
  1750. << ": expected operand P to be a " << total_bit_width
  1751. << "-bit int scalar";
  1752. CompileSuccessfully(GenerateShaderCode(body.str()));
  1753. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1754. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
  1755. }
  1756. TEST_P(ValidateGlslStd450Unpack, ResultPWrongBitWidth) {
  1757. const std::string ext_inst_name = GetParam();
  1758. const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
  1759. const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
  1760. const uint32_t total_bit_width = num_components * packed_bit_width;
  1761. const uint32_t wrong_bit_width = total_bit_width == 32 ? 64 : 32;
  1762. const std::string result_type_str =
  1763. num_components == 2 ? "%f32vec2" : " %f32vec4";
  1764. std::ostringstream body;
  1765. body << "%val1 = OpExtInst " << result_type_str << " %extinst "
  1766. << ext_inst_name << " %u" << wrong_bit_width << "_1\n";
  1767. std::ostringstream expected;
  1768. expected << "GLSL.std.450 " << ext_inst_name
  1769. << ": expected operand P to be a " << total_bit_width
  1770. << "-bit int scalar";
  1771. CompileSuccessfully(GenerateShaderCode(body.str()));
  1772. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1773. EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
  1774. }
  1775. INSTANTIATE_TEST_SUITE_P(AllUnpack, ValidateGlslStd450Unpack,
  1776. ::testing::ValuesIn(std::vector<std::string>{
  1777. "UnpackSnorm4x8",
  1778. "UnpackUnorm4x8",
  1779. "UnpackSnorm2x16",
  1780. "UnpackUnorm2x16",
  1781. "UnpackHalf2x16",
  1782. }));
  1783. TEST_F(ValidateExtInst, UnpackDouble2x32Success) {
  1784. const std::string body = R"(
  1785. %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %f64_1
  1786. )";
  1787. CompileSuccessfully(GenerateShaderCode(body));
  1788. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1789. }
  1790. TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotVector) {
  1791. const std::string body = R"(
  1792. %val1 = OpExtInst %u64 %extinst UnpackDouble2x32 %f64_1
  1793. )";
  1794. CompileSuccessfully(GenerateShaderCode(body));
  1795. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1796. EXPECT_THAT(getDiagnosticString(),
  1797. HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
  1798. "to be a 32-bit int vector of size 2"));
  1799. }
  1800. TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotIntVector) {
  1801. const std::string body = R"(
  1802. %val1 = OpExtInst %f32vec2 %extinst UnpackDouble2x32 %f64_1
  1803. )";
  1804. CompileSuccessfully(GenerateShaderCode(body));
  1805. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1806. EXPECT_THAT(getDiagnosticString(),
  1807. HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
  1808. "to be a 32-bit int vector of size 2"));
  1809. }
  1810. TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotInt32Vector) {
  1811. const std::string body = R"(
  1812. %val1 = OpExtInst %u64vec2 %extinst UnpackDouble2x32 %f64_1
  1813. )";
  1814. CompileSuccessfully(GenerateShaderCode(body));
  1815. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1816. EXPECT_THAT(getDiagnosticString(),
  1817. HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
  1818. "to be a 32-bit int vector of size 2"));
  1819. }
  1820. TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeWrongSize) {
  1821. const std::string body = R"(
  1822. %val1 = OpExtInst %u32vec4 %extinst UnpackDouble2x32 %f64_1
  1823. )";
  1824. CompileSuccessfully(GenerateShaderCode(body));
  1825. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1826. EXPECT_THAT(getDiagnosticString(),
  1827. HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
  1828. "to be a 32-bit int vector of size 2"));
  1829. }
  1830. TEST_F(ValidateExtInst, UnpackDouble2x32VNotFloat) {
  1831. const std::string body = R"(
  1832. %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %u64_1
  1833. )";
  1834. CompileSuccessfully(GenerateShaderCode(body));
  1835. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1836. EXPECT_THAT(getDiagnosticString(),
  1837. HasSubstr("GLSL.std.450 UnpackDouble2x32: expected operand V to "
  1838. "be a 64-bit float scalar"));
  1839. }
  1840. TEST_F(ValidateExtInst, UnpackDouble2x32VNotFloat64) {
  1841. const std::string body = R"(
  1842. %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %f32_1
  1843. )";
  1844. CompileSuccessfully(GenerateShaderCode(body));
  1845. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1846. EXPECT_THAT(getDiagnosticString(),
  1847. HasSubstr("GLSL.std.450 UnpackDouble2x32: expected operand V to "
  1848. "be a 64-bit float scalar"));
  1849. }
  1850. TEST_F(ValidateExtInst, GlslStd450LengthSuccess) {
  1851. const std::string body = R"(
  1852. %val1 = OpExtInst %f32 %extinst Length %f32_1
  1853. %val2 = OpExtInst %f32 %extinst Length %f32vec2_01
  1854. %val3 = OpExtInst %f32 %extinst Length %f32vec4_0123
  1855. )";
  1856. CompileSuccessfully(GenerateShaderCode(body));
  1857. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1858. }
  1859. TEST_F(ValidateExtInst, GlslStd450LengthIntResultType) {
  1860. const std::string body = R"(
  1861. %val1 = OpExtInst %u32 %extinst Length %f32vec2_01
  1862. )";
  1863. CompileSuccessfully(GenerateShaderCode(body));
  1864. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1865. EXPECT_THAT(getDiagnosticString(),
  1866. HasSubstr("GLSL.std.450 Length: "
  1867. "expected Result Type to be a float scalar type"));
  1868. }
  1869. TEST_F(ValidateExtInst, GlslStd450LengthIntX) {
  1870. const std::string body = R"(
  1871. %val1 = OpExtInst %f32 %extinst Length %u32vec2_01
  1872. )";
  1873. CompileSuccessfully(GenerateShaderCode(body));
  1874. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1875. EXPECT_THAT(getDiagnosticString(),
  1876. HasSubstr("GLSL.std.450 Length: "
  1877. "expected operand X to be of float scalar or "
  1878. "vector type"));
  1879. }
  1880. TEST_F(ValidateExtInst, GlslStd450LengthDifferentType) {
  1881. const std::string body = R"(
  1882. %val1 = OpExtInst %f64 %extinst Length %f32vec2_01
  1883. )";
  1884. CompileSuccessfully(GenerateShaderCode(body));
  1885. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1886. EXPECT_THAT(getDiagnosticString(),
  1887. HasSubstr("GLSL.std.450 Length: "
  1888. "expected operand X component type to be equal to "
  1889. "Result Type"));
  1890. }
  1891. TEST_F(ValidateExtInst, GlslStd450DistanceSuccess) {
  1892. const std::string body = R"(
  1893. %val1 = OpExtInst %f32 %extinst Distance %f32_0 %f32_1
  1894. %val2 = OpExtInst %f32 %extinst Distance %f32vec2_01 %f32vec2_12
  1895. %val3 = OpExtInst %f32 %extinst Distance %f32vec4_0123 %f32vec4_1234
  1896. )";
  1897. CompileSuccessfully(GenerateShaderCode(body));
  1898. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1899. }
  1900. TEST_F(ValidateExtInst, GlslStd450DistanceIntResultType) {
  1901. const std::string body = R"(
  1902. %val1 = OpExtInst %u32 %extinst Distance %f32vec2_01 %f32vec2_12
  1903. )";
  1904. CompileSuccessfully(GenerateShaderCode(body));
  1905. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1906. EXPECT_THAT(getDiagnosticString(),
  1907. HasSubstr("GLSL.std.450 Distance: "
  1908. "expected Result Type to be a float scalar type"));
  1909. }
  1910. TEST_F(ValidateExtInst, GlslStd450DistanceIntP0) {
  1911. const std::string body = R"(
  1912. %val1 = OpExtInst %f32 %extinst Distance %u32_0 %f32_1
  1913. )";
  1914. CompileSuccessfully(GenerateShaderCode(body));
  1915. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1916. EXPECT_THAT(getDiagnosticString(),
  1917. HasSubstr("GLSL.std.450 Distance: "
  1918. "expected operand P0 to be of float scalar or "
  1919. "vector type"));
  1920. }
  1921. TEST_F(ValidateExtInst, GlslStd450DistanceF64VectorP0) {
  1922. const std::string body = R"(
  1923. %val1 = OpExtInst %f32 %extinst Distance %f64vec2_01 %f32vec2_12
  1924. )";
  1925. CompileSuccessfully(GenerateShaderCode(body));
  1926. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1927. EXPECT_THAT(getDiagnosticString(),
  1928. HasSubstr("GLSL.std.450 Distance: "
  1929. "expected operand P0 component type to be equal to "
  1930. "Result Type"));
  1931. }
  1932. TEST_F(ValidateExtInst, GlslStd450DistanceIntP1) {
  1933. const std::string body = R"(
  1934. %val1 = OpExtInst %f32 %extinst Distance %f32_0 %u32_1
  1935. )";
  1936. CompileSuccessfully(GenerateShaderCode(body));
  1937. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1938. EXPECT_THAT(getDiagnosticString(),
  1939. HasSubstr("GLSL.std.450 Distance: "
  1940. "expected operand P1 to be of float scalar or "
  1941. "vector type"));
  1942. }
  1943. TEST_F(ValidateExtInst, GlslStd450DistanceF64VectorP1) {
  1944. const std::string body = R"(
  1945. %val1 = OpExtInst %f32 %extinst Distance %f32vec2_12 %f64vec2_01
  1946. )";
  1947. CompileSuccessfully(GenerateShaderCode(body));
  1948. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1949. EXPECT_THAT(getDiagnosticString(),
  1950. HasSubstr("GLSL.std.450 Distance: "
  1951. "expected operand P1 component type to be equal to "
  1952. "Result Type"));
  1953. }
  1954. TEST_F(ValidateExtInst, GlslStd450DistanceDifferentSize) {
  1955. const std::string body = R"(
  1956. %val1 = OpExtInst %f32 %extinst Distance %f32vec2_01 %f32vec4_0123
  1957. )";
  1958. CompileSuccessfully(GenerateShaderCode(body));
  1959. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1960. EXPECT_THAT(getDiagnosticString(),
  1961. HasSubstr("GLSL.std.450 Distance: "
  1962. "expected operands P0 and P1 to have the same number "
  1963. "of components"));
  1964. }
  1965. TEST_F(ValidateExtInst, GlslStd450CrossSuccess) {
  1966. const std::string body = R"(
  1967. %val1 = OpExtInst %f32vec3 %extinst Cross %f32vec3_012 %f32vec3_123
  1968. )";
  1969. CompileSuccessfully(GenerateShaderCode(body));
  1970. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  1971. }
  1972. TEST_F(ValidateExtInst, GlslStd450CrossIntVectorResultType) {
  1973. const std::string body = R"(
  1974. %val1 = OpExtInst %u32vec3 %extinst Cross %f32vec3_012 %f32vec3_123
  1975. )";
  1976. CompileSuccessfully(GenerateShaderCode(body));
  1977. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1978. EXPECT_THAT(getDiagnosticString(),
  1979. HasSubstr("GLSL.std.450 Cross: "
  1980. "expected Result Type to be a float vector type"));
  1981. }
  1982. TEST_F(ValidateExtInst, GlslStd450CrossResultTypeWrongSize) {
  1983. const std::string body = R"(
  1984. %val1 = OpExtInst %f32vec2 %extinst Cross %f32vec3_012 %f32vec3_123
  1985. )";
  1986. CompileSuccessfully(GenerateShaderCode(body));
  1987. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1988. EXPECT_THAT(getDiagnosticString(),
  1989. HasSubstr("GLSL.std.450 Cross: "
  1990. "expected Result Type to have 3 components"));
  1991. }
  1992. TEST_F(ValidateExtInst, GlslStd450CrossXWrongType) {
  1993. const std::string body = R"(
  1994. %val1 = OpExtInst %f32vec3 %extinst Cross %f64vec3_012 %f32vec3_123
  1995. )";
  1996. CompileSuccessfully(GenerateShaderCode(body));
  1997. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  1998. EXPECT_THAT(getDiagnosticString(),
  1999. HasSubstr("GLSL.std.450 Cross: "
  2000. "expected operand X type to be equal to Result Type"));
  2001. }
  2002. TEST_F(ValidateExtInst, GlslStd450CrossYWrongType) {
  2003. const std::string body = R"(
  2004. %val1 = OpExtInst %f32vec3 %extinst Cross %f32vec3_123 %f64vec3_012
  2005. )";
  2006. CompileSuccessfully(GenerateShaderCode(body));
  2007. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2008. EXPECT_THAT(getDiagnosticString(),
  2009. HasSubstr("GLSL.std.450 Cross: "
  2010. "expected operand Y type to be equal to Result Type"));
  2011. }
  2012. TEST_F(ValidateExtInst, GlslStd450RefractSuccess) {
  2013. const std::string body = R"(
  2014. %val1 = OpExtInst %f32 %extinst Refract %f32_1 %f32_1 %f32_1
  2015. %val2 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f16_1
  2016. )";
  2017. CompileSuccessfully(GenerateShaderCode(body));
  2018. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2019. }
  2020. TEST_F(ValidateExtInst, GlslStd450RefractIntVectorResultType) {
  2021. const std::string body = R"(
  2022. %val1 = OpExtInst %u32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f32_1
  2023. )";
  2024. CompileSuccessfully(GenerateShaderCode(body));
  2025. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2026. EXPECT_THAT(getDiagnosticString(),
  2027. HasSubstr("GLSL.std.450 Refract: "
  2028. "expected Result Type to be a float scalar or "
  2029. "vector type"));
  2030. }
  2031. TEST_F(ValidateExtInst, GlslStd450RefractIntVectorI) {
  2032. const std::string body = R"(
  2033. %val1 = OpExtInst %f32vec2 %extinst Refract %u32vec2_01 %f32vec2_01 %f32_1
  2034. )";
  2035. CompileSuccessfully(GenerateShaderCode(body));
  2036. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2037. EXPECT_THAT(getDiagnosticString(),
  2038. HasSubstr("GLSL.std.450 Refract: "
  2039. "expected operand I to be of type equal to "
  2040. "Result Type"));
  2041. }
  2042. TEST_F(ValidateExtInst, GlslStd450RefractIntVectorN) {
  2043. const std::string body = R"(
  2044. %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %u32vec2_01 %f32_1
  2045. )";
  2046. CompileSuccessfully(GenerateShaderCode(body));
  2047. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2048. EXPECT_THAT(getDiagnosticString(),
  2049. HasSubstr("GLSL.std.450 Refract: "
  2050. "expected operand N to be of type equal to "
  2051. "Result Type"));
  2052. }
  2053. TEST_F(ValidateExtInst, GlslStd450RefractIntEta) {
  2054. const std::string body = R"(
  2055. %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %u32_1
  2056. )";
  2057. CompileSuccessfully(GenerateShaderCode(body));
  2058. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2059. EXPECT_THAT(getDiagnosticString(),
  2060. HasSubstr("GLSL.std.450 Refract: "
  2061. "expected operand Eta to be a float scalar"));
  2062. }
  2063. TEST_F(ValidateExtInst, GlslStd450RefractFloat64Eta) {
  2064. // SPIR-V issue 337: Eta can be 64-bit float scalar.
  2065. const std::string body = R"(
  2066. %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f64_1
  2067. )";
  2068. CompileSuccessfully(GenerateShaderCode(body));
  2069. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2070. EXPECT_THAT(getDiagnosticString(), Eq(""));
  2071. }
  2072. TEST_F(ValidateExtInst, GlslStd450RefractVectorEta) {
  2073. const std::string body = R"(
  2074. %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f32vec2_01
  2075. )";
  2076. CompileSuccessfully(GenerateShaderCode(body));
  2077. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2078. EXPECT_THAT(getDiagnosticString(),
  2079. HasSubstr("GLSL.std.450 Refract: "
  2080. "expected operand Eta to be a float scalar"));
  2081. }
  2082. TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidSuccess) {
  2083. const std::string body = R"(
  2084. %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
  2085. %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %f32vec2_input
  2086. )";
  2087. CompileSuccessfully(
  2088. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2089. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2090. }
  2091. TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidInternalSuccess) {
  2092. const std::string body = R"(
  2093. %ld1 = OpLoad %f32 %f32_input
  2094. %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %ld1
  2095. %ld2 = OpLoad %f32vec2 %f32vec2_input
  2096. %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %ld2
  2097. )";
  2098. CompileSuccessfully(
  2099. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2100. getValidatorOptions()->before_hlsl_legalization = true;
  2101. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2102. }
  2103. TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidInternalInvalidDataF32) {
  2104. const std::string body = R"(
  2105. %ld1 = OpLoad %f32 %f32_input
  2106. %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %ld1
  2107. )";
  2108. CompileSuccessfully(
  2109. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2110. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2111. EXPECT_THAT(getDiagnosticString(),
  2112. HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
  2113. "expected Interpolant to be a pointer"));
  2114. }
  2115. TEST_F(ValidateExtInst,
  2116. GlslStd450InterpolateAtCentroidInternalInvalidDataF32Vec2) {
  2117. const std::string body = R"(
  2118. %ld2 = OpLoad %f32vec2 %f32vec2_input
  2119. %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %ld2
  2120. )";
  2121. CompileSuccessfully(
  2122. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2123. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2124. EXPECT_THAT(getDiagnosticString(),
  2125. HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
  2126. "expected Interpolant to be a pointer"));
  2127. }
  2128. TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNoCapability) {
  2129. const std::string body = R"(
  2130. %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
  2131. )";
  2132. CompileSuccessfully(GenerateShaderCode(body));
  2133. ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
  2134. EXPECT_THAT(getDiagnosticString(),
  2135. HasSubstr("GLSL.std.450 InterpolateAtCentroid requires "
  2136. "capability InterpolationFunction"));
  2137. }
  2138. TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidIntResultType) {
  2139. const std::string body = R"(
  2140. %val1 = OpExtInst %u32 %extinst InterpolateAtCentroid %f32_input
  2141. )";
  2142. CompileSuccessfully(
  2143. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2144. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2145. EXPECT_THAT(getDiagnosticString(),
  2146. HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
  2147. "expected Result Type to be a 32-bit float scalar "
  2148. "or vector type"));
  2149. }
  2150. TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidF64ResultType) {
  2151. const std::string body = R"(
  2152. %val1 = OpExtInst %f64 %extinst InterpolateAtCentroid %f32_input
  2153. )";
  2154. CompileSuccessfully(
  2155. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2156. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2157. EXPECT_THAT(getDiagnosticString(),
  2158. HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
  2159. "expected Result Type to be a 32-bit float scalar "
  2160. "or vector type"));
  2161. }
  2162. TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNotPointer) {
  2163. const std::string body = R"(
  2164. %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_1
  2165. )";
  2166. CompileSuccessfully(
  2167. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2168. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2169. EXPECT_THAT(getDiagnosticString(),
  2170. HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
  2171. "expected Interpolant to be a pointer"));
  2172. }
  2173. TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongDataType) {
  2174. const std::string body = R"(
  2175. %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32vec2_input
  2176. )";
  2177. CompileSuccessfully(
  2178. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2179. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2180. EXPECT_THAT(getDiagnosticString(),
  2181. HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
  2182. "expected Interpolant data type to be equal to "
  2183. "Result Type"));
  2184. }
  2185. TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongStorageClass) {
  2186. const std::string body = R"(
  2187. %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_output
  2188. )";
  2189. CompileSuccessfully(
  2190. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2191. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2192. EXPECT_THAT(getDiagnosticString(),
  2193. HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
  2194. "expected Interpolant storage class to be Input"));
  2195. }
  2196. TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongExecutionModel) {
  2197. const std::string body = R"(
  2198. %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
  2199. )";
  2200. CompileSuccessfully(GenerateShaderCode(
  2201. body, "OpCapability InterpolationFunction\n", "Vertex"));
  2202. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2203. EXPECT_THAT(getDiagnosticString(),
  2204. HasSubstr("GLSL.std.450 InterpolateAtCentroid requires "
  2205. "Fragment execution model"));
  2206. }
  2207. TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleSuccess) {
  2208. const std::string body = R"(
  2209. %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
  2210. %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %f32vec2_input %u32_1
  2211. )";
  2212. CompileSuccessfully(
  2213. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2214. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2215. }
  2216. TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleInternalSuccess) {
  2217. const std::string body = R"(
  2218. %ld1 = OpLoad %f32 %f32_input
  2219. %val1 = OpExtInst %f32 %extinst InterpolateAtSample %ld1 %u32_1
  2220. %ld2 = OpLoad %f32vec2 %f32vec2_input
  2221. %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %ld2 %u32_1
  2222. )";
  2223. CompileSuccessfully(
  2224. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2225. getValidatorOptions()->before_hlsl_legalization = true;
  2226. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2227. }
  2228. TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleInternalInvalidDataF32) {
  2229. const std::string body = R"(
  2230. %ld1 = OpLoad %f32 %f32_input
  2231. %val1 = OpExtInst %f32 %extinst InterpolateAtSample %ld1 %u32_1
  2232. )";
  2233. CompileSuccessfully(
  2234. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2235. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2236. EXPECT_THAT(getDiagnosticString(),
  2237. HasSubstr("GLSL.std.450 InterpolateAtSample: "
  2238. "expected Interpolant to be a pointer"));
  2239. }
  2240. TEST_F(ValidateExtInst,
  2241. GlslStd450InterpolateAtSampleInternalInvalidDataF32Vec2) {
  2242. const std::string body = R"(
  2243. %ld2 = OpLoad %f32vec2 %f32vec2_input
  2244. %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %ld2 %u32_1
  2245. )";
  2246. CompileSuccessfully(
  2247. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2248. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2249. EXPECT_THAT(getDiagnosticString(),
  2250. HasSubstr("GLSL.std.450 InterpolateAtSample: "
  2251. "expected Interpolant to be a pointer"));
  2252. }
  2253. TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNoCapability) {
  2254. const std::string body = R"(
  2255. %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
  2256. )";
  2257. CompileSuccessfully(GenerateShaderCode(body));
  2258. ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
  2259. EXPECT_THAT(getDiagnosticString(),
  2260. HasSubstr("GLSL.std.450 InterpolateAtSample requires "
  2261. "capability InterpolationFunction"));
  2262. }
  2263. TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleIntResultType) {
  2264. const std::string body = R"(
  2265. %val1 = OpExtInst %u32 %extinst InterpolateAtSample %f32_input %u32_1
  2266. )";
  2267. CompileSuccessfully(
  2268. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2269. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2270. EXPECT_THAT(getDiagnosticString(),
  2271. HasSubstr("GLSL.std.450 InterpolateAtSample: "
  2272. "expected Result Type to be a 32-bit float scalar "
  2273. "or vector type"));
  2274. }
  2275. TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleF64ResultType) {
  2276. const std::string body = R"(
  2277. %val1 = OpExtInst %f64 %extinst InterpolateAtSample %f32_input %u32_1
  2278. )";
  2279. CompileSuccessfully(
  2280. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2281. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2282. EXPECT_THAT(getDiagnosticString(),
  2283. HasSubstr("GLSL.std.450 InterpolateAtSample: "
  2284. "expected Result Type to be a 32-bit float scalar "
  2285. "or vector type"));
  2286. }
  2287. TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNotPointer) {
  2288. const std::string body = R"(
  2289. %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_1 %u32_1
  2290. )";
  2291. CompileSuccessfully(
  2292. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2293. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2294. EXPECT_THAT(getDiagnosticString(),
  2295. HasSubstr("GLSL.std.450 InterpolateAtSample: "
  2296. "expected Interpolant to be a pointer"));
  2297. }
  2298. TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongDataType) {
  2299. const std::string body = R"(
  2300. %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32vec2_input %u32_1
  2301. )";
  2302. CompileSuccessfully(
  2303. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2304. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2305. EXPECT_THAT(getDiagnosticString(),
  2306. HasSubstr("GLSL.std.450 InterpolateAtSample: "
  2307. "expected Interpolant data type to be equal to "
  2308. "Result Type"));
  2309. }
  2310. TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongStorageClass) {
  2311. const std::string body = R"(
  2312. %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_output %u32_1
  2313. )";
  2314. CompileSuccessfully(
  2315. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2316. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2317. EXPECT_THAT(getDiagnosticString(),
  2318. HasSubstr("GLSL.std.450 InterpolateAtSample: "
  2319. "expected Interpolant storage class to be Input"));
  2320. }
  2321. TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleFloatSample) {
  2322. const std::string body = R"(
  2323. %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %f32_1
  2324. )";
  2325. CompileSuccessfully(
  2326. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2327. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2328. EXPECT_THAT(getDiagnosticString(),
  2329. HasSubstr("GLSL.std.450 InterpolateAtSample: "
  2330. "expected Sample to be 32-bit integer"));
  2331. }
  2332. TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleU64Sample) {
  2333. const std::string body = R"(
  2334. %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u64_1
  2335. )";
  2336. CompileSuccessfully(
  2337. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2338. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2339. EXPECT_THAT(getDiagnosticString(),
  2340. HasSubstr("GLSL.std.450 InterpolateAtSample: "
  2341. "expected Sample to be 32-bit integer"));
  2342. }
  2343. TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongExecutionModel) {
  2344. const std::string body = R"(
  2345. %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
  2346. )";
  2347. CompileSuccessfully(GenerateShaderCode(
  2348. body, "OpCapability InterpolationFunction\n", "Vertex"));
  2349. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2350. EXPECT_THAT(getDiagnosticString(),
  2351. HasSubstr("GLSL.std.450 InterpolateAtSample requires "
  2352. "Fragment execution model"));
  2353. }
  2354. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetSuccess) {
  2355. const std::string body = R"(
  2356. %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
  2357. %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01
  2358. )";
  2359. CompileSuccessfully(
  2360. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2361. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2362. }
  2363. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetInternalSuccess) {
  2364. const std::string body = R"(
  2365. %ld1 = OpLoad %f32 %f32_input
  2366. %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %ld1 %f32vec2_01
  2367. %ld2 = OpLoad %f32vec2 %f32vec2_input
  2368. %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %ld2 %f32vec2_01
  2369. )";
  2370. CompileSuccessfully(
  2371. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2372. getValidatorOptions()->before_hlsl_legalization = true;
  2373. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2374. }
  2375. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetInternalInvalidDataF32) {
  2376. const std::string body = R"(
  2377. %ld1 = OpLoad %f32 %f32_input
  2378. %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %ld1 %f32vec2_01
  2379. )";
  2380. CompileSuccessfully(
  2381. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2382. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2383. EXPECT_THAT(getDiagnosticString(),
  2384. HasSubstr("GLSL.std.450 InterpolateAtOffset: "
  2385. "expected Interpolant to be a pointer"));
  2386. }
  2387. TEST_F(ValidateExtInst,
  2388. GlslStd450InterpolateAtOffsetInternalInvalidDataF32Vec2) {
  2389. const std::string body = R"(
  2390. %ld2 = OpLoad %f32vec2 %f32vec2_input
  2391. %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %ld2 %f32vec2_01
  2392. )";
  2393. CompileSuccessfully(
  2394. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2395. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2396. EXPECT_THAT(getDiagnosticString(),
  2397. HasSubstr("GLSL.std.450 InterpolateAtOffset: "
  2398. "expected Interpolant to be a pointer"));
  2399. }
  2400. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNoCapability) {
  2401. const std::string body = R"(
  2402. %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
  2403. )";
  2404. CompileSuccessfully(GenerateShaderCode(body));
  2405. ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
  2406. EXPECT_THAT(getDiagnosticString(),
  2407. HasSubstr("GLSL.std.450 InterpolateAtOffset requires "
  2408. "capability InterpolationFunction"));
  2409. }
  2410. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetIntResultType) {
  2411. const std::string body = R"(
  2412. %val1 = OpExtInst %u32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
  2413. )";
  2414. CompileSuccessfully(
  2415. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2416. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2417. EXPECT_THAT(getDiagnosticString(),
  2418. HasSubstr("GLSL.std.450 InterpolateAtOffset: "
  2419. "expected Result Type to be a 32-bit float scalar "
  2420. "or vector type"));
  2421. }
  2422. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetF64ResultType) {
  2423. const std::string body = R"(
  2424. %val1 = OpExtInst %f64 %extinst InterpolateAtOffset %f32_input %f32vec2_01
  2425. )";
  2426. CompileSuccessfully(
  2427. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2428. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2429. EXPECT_THAT(getDiagnosticString(),
  2430. HasSubstr("GLSL.std.450 InterpolateAtOffset: "
  2431. "expected Result Type to be a 32-bit float scalar "
  2432. "or vector type"));
  2433. }
  2434. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNotPointer) {
  2435. const std::string body = R"(
  2436. %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_1 %f32vec2_01
  2437. )";
  2438. CompileSuccessfully(
  2439. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2440. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2441. EXPECT_THAT(getDiagnosticString(),
  2442. HasSubstr("GLSL.std.450 InterpolateAtOffset: "
  2443. "expected Interpolant to be a pointer"));
  2444. }
  2445. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongDataType) {
  2446. const std::string body = R"(
  2447. %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01
  2448. )";
  2449. CompileSuccessfully(
  2450. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2451. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2452. EXPECT_THAT(getDiagnosticString(),
  2453. HasSubstr("GLSL.std.450 InterpolateAtOffset: "
  2454. "expected Interpolant data type to be equal to "
  2455. "Result Type"));
  2456. }
  2457. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongStorageClass) {
  2458. const std::string body = R"(
  2459. %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_output %f32vec2_01
  2460. )";
  2461. CompileSuccessfully(
  2462. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2463. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2464. EXPECT_THAT(getDiagnosticString(),
  2465. HasSubstr("GLSL.std.450 InterpolateAtOffset: "
  2466. "expected Interpolant storage class to be Input"));
  2467. }
  2468. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector) {
  2469. const std::string body = R"(
  2470. %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32_0
  2471. )";
  2472. CompileSuccessfully(
  2473. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2474. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2475. EXPECT_THAT(getDiagnosticString(),
  2476. HasSubstr("GLSL.std.450 InterpolateAtOffset: "
  2477. "expected Offset to be a vector of 2 32-bit floats"));
  2478. }
  2479. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector2) {
  2480. const std::string body = R"(
  2481. %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec3_012
  2482. )";
  2483. CompileSuccessfully(
  2484. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2485. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2486. EXPECT_THAT(getDiagnosticString(),
  2487. HasSubstr("GLSL.std.450 InterpolateAtOffset: "
  2488. "expected Offset to be a vector of 2 32-bit floats"));
  2489. }
  2490. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloatVector) {
  2491. const std::string body = R"(
  2492. %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %u32vec2_01
  2493. )";
  2494. CompileSuccessfully(
  2495. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2496. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2497. EXPECT_THAT(getDiagnosticString(),
  2498. HasSubstr("GLSL.std.450 InterpolateAtOffset: "
  2499. "expected Offset to be a vector of 2 32-bit floats"));
  2500. }
  2501. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloat32Vector) {
  2502. const std::string body = R"(
  2503. %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f64vec2_01
  2504. )";
  2505. CompileSuccessfully(
  2506. GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
  2507. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2508. EXPECT_THAT(getDiagnosticString(),
  2509. HasSubstr("GLSL.std.450 InterpolateAtOffset: "
  2510. "expected Offset to be a vector of 2 32-bit floats"));
  2511. }
  2512. TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongExecutionModel) {
  2513. const std::string body = R"(
  2514. %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
  2515. )";
  2516. CompileSuccessfully(GenerateShaderCode(
  2517. body, "OpCapability InterpolationFunction\n", "Vertex"));
  2518. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  2519. EXPECT_THAT(getDiagnosticString(),
  2520. HasSubstr("GLSL.std.450 InterpolateAtOffset requires "
  2521. "Fragment execution model"));
  2522. }
  2523. TEST_P(ValidateOpenCLStdSqrtLike, Success) {
  2524. const std::string ext_inst_name = GetParam();
  2525. std::ostringstream ss;
  2526. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
  2527. ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  2528. << " %f32vec2_01\n";
  2529. ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
  2530. << " %f32vec4_0123\n";
  2531. ss << "%val4 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n";
  2532. CompileSuccessfully(GenerateKernelCode(ss.str()));
  2533. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2534. }
  2535. TEST_P(ValidateOpenCLStdSqrtLike, IntResultType) {
  2536. const std::string ext_inst_name = GetParam();
  2537. const std::string body =
  2538. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
  2539. CompileSuccessfully(GenerateKernelCode(body));
  2540. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2541. EXPECT_THAT(getDiagnosticString(),
  2542. HasSubstr("OpenCL.std " + ext_inst_name +
  2543. ": expected Result Type to be a float scalar "
  2544. "or vector type"));
  2545. }
  2546. TEST_P(ValidateOpenCLStdSqrtLike, IntOperand) {
  2547. const std::string ext_inst_name = GetParam();
  2548. const std::string body =
  2549. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
  2550. CompileSuccessfully(GenerateKernelCode(body));
  2551. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2552. EXPECT_THAT(getDiagnosticString(),
  2553. HasSubstr("OpenCL.std " + ext_inst_name +
  2554. ": expected types of all operands to be equal to "
  2555. "Result Type"));
  2556. }
  2557. INSTANTIATE_TEST_SUITE_P(
  2558. AllSqrtLike, ValidateOpenCLStdSqrtLike,
  2559. ::testing::ValuesIn(std::vector<std::string>{
  2560. "acos", "acosh", "acospi", "asin",
  2561. "asinh", "asinpi", "atan", "atanh",
  2562. "atanpi", "cbrt", "ceil", "cos",
  2563. "cosh", "cospi", "erfc", "erf",
  2564. "exp", "exp2", "exp10", "expm1",
  2565. "fabs", "floor", "log", "log2",
  2566. "log10", "log1p", "logb", "rint",
  2567. "round", "rsqrt", "sin", "sinh",
  2568. "sinpi", "sqrt", "tan", "tanh",
  2569. "tanpi", "tgamma", "trunc", "half_cos",
  2570. "half_exp", "half_exp2", "half_exp10", "half_log",
  2571. "half_log2", "half_log10", "half_recip", "half_rsqrt",
  2572. "half_sin", "half_sqrt", "half_tan", "lgamma",
  2573. "native_cos", "native_exp", "native_exp2", "native_exp10",
  2574. "native_log", "native_log2", "native_log10", "native_recip",
  2575. "native_rsqrt", "native_sin", "native_sqrt", "native_tan",
  2576. "degrees", "radians", "sign",
  2577. }));
  2578. TEST_P(ValidateOpenCLStdFMinLike, Success) {
  2579. const std::string ext_inst_name = GetParam();
  2580. std::ostringstream ss;
  2581. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  2582. << " %f32_0 %f32_1\n";
  2583. ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  2584. << " %f32vec2_01 %f32vec2_12\n";
  2585. ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
  2586. << " %f64_0 %f64_0\n";
  2587. CompileSuccessfully(GenerateKernelCode(ss.str()));
  2588. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2589. }
  2590. TEST_P(ValidateOpenCLStdFMinLike, IntResultType) {
  2591. const std::string ext_inst_name = GetParam();
  2592. const std::string body =
  2593. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n";
  2594. CompileSuccessfully(GenerateKernelCode(body));
  2595. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2596. EXPECT_THAT(getDiagnosticString(),
  2597. HasSubstr("OpenCL.std " + ext_inst_name +
  2598. ": expected Result Type to be a float scalar "
  2599. "or vector type"));
  2600. }
  2601. TEST_P(ValidateOpenCLStdFMinLike, IntOperand1) {
  2602. const std::string ext_inst_name = GetParam();
  2603. const std::string body =
  2604. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
  2605. CompileSuccessfully(GenerateKernelCode(body));
  2606. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2607. EXPECT_THAT(getDiagnosticString(),
  2608. HasSubstr("OpenCL.std " + ext_inst_name +
  2609. ": expected types of all operands to be equal to "
  2610. "Result Type"));
  2611. }
  2612. TEST_P(ValidateOpenCLStdFMinLike, IntOperand2) {
  2613. const std::string ext_inst_name = GetParam();
  2614. const std::string body =
  2615. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
  2616. CompileSuccessfully(GenerateKernelCode(body));
  2617. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2618. EXPECT_THAT(getDiagnosticString(),
  2619. HasSubstr("OpenCL.std " + ext_inst_name +
  2620. ": expected types of all operands to be equal to "
  2621. "Result Type"));
  2622. }
  2623. INSTANTIATE_TEST_SUITE_P(AllFMinLike, ValidateOpenCLStdFMinLike,
  2624. ::testing::ValuesIn(std::vector<std::string>{
  2625. "atan2", "atan2pi", "copysign",
  2626. "fdim", "fmax", "fmin",
  2627. "fmod", "maxmag", "minmag",
  2628. "hypot", "nextafter", "pow",
  2629. "powr", "remainder", "half_divide",
  2630. "half_powr", "native_divide", "native_powr",
  2631. "step", "fmax_common", "fmin_common",
  2632. }));
  2633. TEST_P(ValidateOpenCLStdFClampLike, Success) {
  2634. const std::string ext_inst_name = GetParam();
  2635. std::ostringstream ss;
  2636. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  2637. << " %f32_0 %f32_1 %f32_2\n";
  2638. ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  2639. << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n";
  2640. ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
  2641. << " %f64_0 %f64_0 %f64_1\n";
  2642. CompileSuccessfully(GenerateKernelCode(ss.str()));
  2643. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2644. }
  2645. TEST_P(ValidateOpenCLStdFClampLike, IntResultType) {
  2646. const std::string ext_inst_name = GetParam();
  2647. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  2648. " %f32_0 %f32_1 %f32_2\n";
  2649. CompileSuccessfully(GenerateKernelCode(body));
  2650. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2651. EXPECT_THAT(getDiagnosticString(),
  2652. HasSubstr("OpenCL.std " + ext_inst_name +
  2653. ": expected Result Type to be a float scalar "
  2654. "or vector type"));
  2655. }
  2656. TEST_P(ValidateOpenCLStdFClampLike, IntOperand1) {
  2657. const std::string ext_inst_name = GetParam();
  2658. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  2659. " %u32_0 %f32_0 %f32_1\n";
  2660. CompileSuccessfully(GenerateKernelCode(body));
  2661. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2662. EXPECT_THAT(getDiagnosticString(),
  2663. HasSubstr("OpenCL.std " + ext_inst_name +
  2664. ": expected types of all operands to be equal to "
  2665. "Result Type"));
  2666. }
  2667. TEST_P(ValidateOpenCLStdFClampLike, IntOperand2) {
  2668. const std::string ext_inst_name = GetParam();
  2669. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  2670. " %f32_0 %u32_0 %f32_1\n";
  2671. CompileSuccessfully(GenerateKernelCode(body));
  2672. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2673. EXPECT_THAT(getDiagnosticString(),
  2674. HasSubstr("OpenCL.std " + ext_inst_name +
  2675. ": expected types of all operands to be equal to "
  2676. "Result Type"));
  2677. }
  2678. TEST_P(ValidateOpenCLStdFClampLike, IntOperand3) {
  2679. const std::string ext_inst_name = GetParam();
  2680. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  2681. " %f32_1 %f32_0 %u32_2\n";
  2682. CompileSuccessfully(GenerateKernelCode(body));
  2683. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2684. EXPECT_THAT(getDiagnosticString(),
  2685. HasSubstr("OpenCL.std " + ext_inst_name +
  2686. ": expected types of all operands to be equal to "
  2687. "Result Type"));
  2688. }
  2689. INSTANTIATE_TEST_SUITE_P(AllFClampLike, ValidateOpenCLStdFClampLike,
  2690. ::testing::ValuesIn(std::vector<std::string>{
  2691. "fma",
  2692. "mad",
  2693. "fclamp",
  2694. "mix",
  2695. "smoothstep",
  2696. }));
  2697. TEST_P(ValidateOpenCLStdSAbsLike, Success) {
  2698. const std::string ext_inst_name = GetParam();
  2699. std::ostringstream ss;
  2700. ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
  2701. ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
  2702. ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
  2703. ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
  2704. ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2705. << " %u32vec2_01\n";
  2706. ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2707. << " %u32vec2_01\n";
  2708. ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2709. << " %u32vec2_01\n";
  2710. ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2711. << " %u32vec2_01\n";
  2712. CompileSuccessfully(GenerateKernelCode(ss.str()));
  2713. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2714. }
  2715. TEST_P(ValidateOpenCLStdSAbsLike, FloatResultType) {
  2716. const std::string ext_inst_name = GetParam();
  2717. const std::string body =
  2718. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
  2719. CompileSuccessfully(GenerateKernelCode(body));
  2720. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2721. EXPECT_THAT(getDiagnosticString(),
  2722. HasSubstr("OpenCL.std " + ext_inst_name +
  2723. ": expected Result Type to be an int scalar "
  2724. "or vector type"));
  2725. }
  2726. TEST_P(ValidateOpenCLStdSAbsLike, FloatOperand) {
  2727. const std::string ext_inst_name = GetParam();
  2728. const std::string body =
  2729. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
  2730. CompileSuccessfully(GenerateKernelCode(body));
  2731. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2732. EXPECT_THAT(
  2733. getDiagnosticString(),
  2734. HasSubstr("OpenCL.std " + ext_inst_name +
  2735. ": expected types of all operands to be equal to Result Type"));
  2736. }
  2737. TEST_P(ValidateOpenCLStdSAbsLike, U64Operand) {
  2738. const std::string ext_inst_name = GetParam();
  2739. const std::string body =
  2740. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0\n";
  2741. CompileSuccessfully(GenerateKernelCode(body));
  2742. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2743. EXPECT_THAT(
  2744. getDiagnosticString(),
  2745. HasSubstr("OpenCL.std " + ext_inst_name +
  2746. ": expected types of all operands to be equal to Result Type"));
  2747. }
  2748. INSTANTIATE_TEST_SUITE_P(AllSAbsLike, ValidateOpenCLStdSAbsLike,
  2749. ::testing::ValuesIn(std::vector<std::string>{
  2750. "s_abs",
  2751. "clz",
  2752. "ctz",
  2753. "popcount",
  2754. "u_abs",
  2755. }));
  2756. TEST_P(ValidateOpenCLStdUMinLike, Success) {
  2757. const std::string ext_inst_name = GetParam();
  2758. std::ostringstream ss;
  2759. ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
  2760. << " %u32_1 %u32_2\n";
  2761. ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
  2762. << " %u32_1 %u32_2\n";
  2763. ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
  2764. << " %u32_1 %u32_2\n";
  2765. ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
  2766. << " %u32_1 %u32_2\n";
  2767. ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2768. << " %u32vec2_01 %u32vec2_01\n";
  2769. ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2770. << " %u32vec2_01 %u32vec2_01\n";
  2771. ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2772. << " %u32vec2_01 %u32vec2_01\n";
  2773. ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2774. << " %u32vec2_01 %u32vec2_01\n";
  2775. ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name
  2776. << " %u64_1 %u64_0\n";
  2777. CompileSuccessfully(GenerateKernelCode(ss.str()));
  2778. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2779. }
  2780. TEST_P(ValidateOpenCLStdUMinLike, FloatResultType) {
  2781. const std::string ext_inst_name = GetParam();
  2782. const std::string body =
  2783. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
  2784. CompileSuccessfully(GenerateKernelCode(body));
  2785. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2786. EXPECT_THAT(getDiagnosticString(),
  2787. HasSubstr("OpenCL.std " + ext_inst_name +
  2788. ": expected Result Type to be an int scalar "
  2789. "or vector type"));
  2790. }
  2791. TEST_P(ValidateOpenCLStdUMinLike, FloatOperand1) {
  2792. const std::string ext_inst_name = GetParam();
  2793. const std::string body =
  2794. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
  2795. CompileSuccessfully(GenerateKernelCode(body));
  2796. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2797. EXPECT_THAT(
  2798. getDiagnosticString(),
  2799. HasSubstr("OpenCL.std " + ext_inst_name +
  2800. ": expected types of all operands to be equal to Result Type"));
  2801. }
  2802. TEST_P(ValidateOpenCLStdUMinLike, FloatOperand2) {
  2803. const std::string ext_inst_name = GetParam();
  2804. const std::string body =
  2805. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
  2806. CompileSuccessfully(GenerateKernelCode(body));
  2807. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2808. EXPECT_THAT(
  2809. getDiagnosticString(),
  2810. HasSubstr("OpenCL.std " + ext_inst_name +
  2811. ": expected types of all operands to be equal to Result Type"));
  2812. }
  2813. TEST_P(ValidateOpenCLStdUMinLike, U64Operand1) {
  2814. const std::string ext_inst_name = GetParam();
  2815. const std::string body =
  2816. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n";
  2817. CompileSuccessfully(GenerateKernelCode(body));
  2818. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2819. EXPECT_THAT(
  2820. getDiagnosticString(),
  2821. HasSubstr("OpenCL.std " + ext_inst_name +
  2822. ": expected types of all operands to be equal to Result Type"));
  2823. }
  2824. TEST_P(ValidateOpenCLStdUMinLike, U64Operand2) {
  2825. const std::string ext_inst_name = GetParam();
  2826. const std::string body =
  2827. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n";
  2828. CompileSuccessfully(GenerateKernelCode(body));
  2829. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2830. EXPECT_THAT(
  2831. getDiagnosticString(),
  2832. HasSubstr("OpenCL.std " + ext_inst_name +
  2833. ": expected types of all operands to be equal to Result Type"));
  2834. }
  2835. INSTANTIATE_TEST_SUITE_P(AllUMinLike, ValidateOpenCLStdUMinLike,
  2836. ::testing::ValuesIn(std::vector<std::string>{
  2837. "s_max",
  2838. "u_max",
  2839. "s_min",
  2840. "u_min",
  2841. "s_abs_diff",
  2842. "s_add_sat",
  2843. "u_add_sat",
  2844. "s_mul_hi",
  2845. "rotate",
  2846. "s_sub_sat",
  2847. "u_sub_sat",
  2848. "s_hadd",
  2849. "u_hadd",
  2850. "s_rhadd",
  2851. "u_rhadd",
  2852. "u_abs_diff",
  2853. "u_mul_hi",
  2854. }));
  2855. TEST_P(ValidateOpenCLStdUClampLike, Success) {
  2856. const std::string ext_inst_name = GetParam();
  2857. std::ostringstream ss;
  2858. ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
  2859. << " %u32_0 %u32_1 %u32_2\n";
  2860. ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
  2861. << " %u32_0 %u32_1 %u32_2\n";
  2862. ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
  2863. << " %u32_0 %u32_1 %u32_2\n";
  2864. ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
  2865. << " %u32_0 %u32_1 %u32_2\n";
  2866. ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2867. << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
  2868. ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2869. << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
  2870. ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2871. << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
  2872. ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2873. << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
  2874. ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name
  2875. << " %u64_1 %u64_0 %u64_1\n";
  2876. CompileSuccessfully(GenerateKernelCode(ss.str()));
  2877. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2878. }
  2879. TEST_P(ValidateOpenCLStdUClampLike, FloatResultType) {
  2880. const std::string ext_inst_name = GetParam();
  2881. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  2882. " %u32_0 %u32_0 %u32_1\n";
  2883. CompileSuccessfully(GenerateKernelCode(body));
  2884. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2885. EXPECT_THAT(getDiagnosticString(),
  2886. HasSubstr("OpenCL.std " + ext_inst_name +
  2887. ": expected Result Type to be an int scalar "
  2888. "or vector type"));
  2889. }
  2890. TEST_P(ValidateOpenCLStdUClampLike, FloatOperand1) {
  2891. const std::string ext_inst_name = GetParam();
  2892. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  2893. " %f32_0 %u32_0 %u32_1\n";
  2894. CompileSuccessfully(GenerateKernelCode(body));
  2895. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2896. EXPECT_THAT(
  2897. getDiagnosticString(),
  2898. HasSubstr("OpenCL.std " + ext_inst_name +
  2899. ": expected types of all operands to be equal to Result Type"));
  2900. }
  2901. TEST_P(ValidateOpenCLStdUClampLike, FloatOperand2) {
  2902. const std::string ext_inst_name = GetParam();
  2903. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  2904. " %u32_0 %f32_0 %u32_1\n";
  2905. CompileSuccessfully(GenerateKernelCode(body));
  2906. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2907. EXPECT_THAT(
  2908. getDiagnosticString(),
  2909. HasSubstr("OpenCL.std " + ext_inst_name +
  2910. ": expected types of all operands to be equal to Result Type"));
  2911. }
  2912. TEST_P(ValidateOpenCLStdUClampLike, FloatOperand3) {
  2913. const std::string ext_inst_name = GetParam();
  2914. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  2915. " %u32_0 %u32_0 %f32_1\n";
  2916. CompileSuccessfully(GenerateKernelCode(body));
  2917. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2918. EXPECT_THAT(
  2919. getDiagnosticString(),
  2920. HasSubstr("OpenCL.std " + ext_inst_name +
  2921. ": expected types of all operands to be equal to Result Type"));
  2922. }
  2923. TEST_P(ValidateOpenCLStdUClampLike, U64Operand1) {
  2924. const std::string ext_inst_name = GetParam();
  2925. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  2926. " %f32_0 %u32_0 %u64_1\n";
  2927. CompileSuccessfully(GenerateKernelCode(body));
  2928. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2929. EXPECT_THAT(
  2930. getDiagnosticString(),
  2931. HasSubstr("OpenCL.std " + ext_inst_name +
  2932. ": expected types of all operands to be equal to Result Type"));
  2933. }
  2934. TEST_P(ValidateOpenCLStdUClampLike, U64Operand2) {
  2935. const std::string ext_inst_name = GetParam();
  2936. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  2937. " %u32_0 %f32_0 %u64_1\n";
  2938. CompileSuccessfully(GenerateKernelCode(body));
  2939. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2940. EXPECT_THAT(
  2941. getDiagnosticString(),
  2942. HasSubstr("OpenCL.std " + ext_inst_name +
  2943. ": expected types of all operands to be equal to Result Type"));
  2944. }
  2945. TEST_P(ValidateOpenCLStdUClampLike, U64Operand3) {
  2946. const std::string ext_inst_name = GetParam();
  2947. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  2948. " %u32_0 %u32_0 %u64_1\n";
  2949. CompileSuccessfully(GenerateKernelCode(body));
  2950. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2951. EXPECT_THAT(
  2952. getDiagnosticString(),
  2953. HasSubstr("OpenCL.std " + ext_inst_name +
  2954. ": expected types of all operands to be equal to Result Type"));
  2955. }
  2956. INSTANTIATE_TEST_SUITE_P(AllUClampLike, ValidateOpenCLStdUClampLike,
  2957. ::testing::ValuesIn(std::vector<std::string>{
  2958. "s_clamp",
  2959. "u_clamp",
  2960. "s_mad_hi",
  2961. "u_mad_sat",
  2962. "s_mad_sat",
  2963. "u_mad_hi",
  2964. }));
  2965. // -------------------------------------------------------------
  2966. TEST_P(ValidateOpenCLStdUMul24Like, Success) {
  2967. const std::string ext_inst_name = GetParam();
  2968. std::ostringstream ss;
  2969. ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
  2970. << " %u32_1 %u32_2\n";
  2971. ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
  2972. << " %u32_1 %u32_2\n";
  2973. ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
  2974. << " %u32_1 %u32_2\n";
  2975. ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
  2976. << " %u32_1 %u32_2\n";
  2977. ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2978. << " %u32vec2_01 %u32vec2_01\n";
  2979. ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2980. << " %u32vec2_01 %u32vec2_01\n";
  2981. ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2982. << " %u32vec2_01 %u32vec2_01\n";
  2983. ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  2984. << " %u32vec2_01 %u32vec2_01\n";
  2985. CompileSuccessfully(GenerateKernelCode(ss.str()));
  2986. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  2987. }
  2988. TEST_P(ValidateOpenCLStdUMul24Like, FloatResultType) {
  2989. const std::string ext_inst_name = GetParam();
  2990. const std::string body =
  2991. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
  2992. CompileSuccessfully(GenerateKernelCode(body));
  2993. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  2994. EXPECT_THAT(
  2995. getDiagnosticString(),
  2996. HasSubstr(
  2997. "OpenCL.std " + ext_inst_name +
  2998. ": expected Result Type to be a 32-bit int scalar or vector type"));
  2999. }
  3000. TEST_P(ValidateOpenCLStdUMul24Like, U64ResultType) {
  3001. const std::string ext_inst_name = GetParam();
  3002. const std::string body =
  3003. "%val1 = OpExtInst %u64 %extinst " + ext_inst_name + " %u64_0 %u64_0\n";
  3004. CompileSuccessfully(GenerateKernelCode(body));
  3005. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3006. EXPECT_THAT(
  3007. getDiagnosticString(),
  3008. HasSubstr(
  3009. "OpenCL.std " + ext_inst_name +
  3010. ": expected Result Type to be a 32-bit int scalar or vector type"));
  3011. }
  3012. TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand1) {
  3013. const std::string ext_inst_name = GetParam();
  3014. const std::string body =
  3015. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
  3016. CompileSuccessfully(GenerateKernelCode(body));
  3017. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3018. EXPECT_THAT(
  3019. getDiagnosticString(),
  3020. HasSubstr("OpenCL.std " + ext_inst_name +
  3021. ": expected types of all operands to be equal to Result Type"));
  3022. }
  3023. TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand2) {
  3024. const std::string ext_inst_name = GetParam();
  3025. const std::string body =
  3026. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
  3027. CompileSuccessfully(GenerateKernelCode(body));
  3028. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3029. EXPECT_THAT(
  3030. getDiagnosticString(),
  3031. HasSubstr("OpenCL.std " + ext_inst_name +
  3032. ": expected types of all operands to be equal to Result Type"));
  3033. }
  3034. TEST_P(ValidateOpenCLStdUMul24Like, U64Operand1) {
  3035. const std::string ext_inst_name = GetParam();
  3036. const std::string body =
  3037. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n";
  3038. CompileSuccessfully(GenerateKernelCode(body));
  3039. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3040. EXPECT_THAT(
  3041. getDiagnosticString(),
  3042. HasSubstr("OpenCL.std " + ext_inst_name +
  3043. ": expected types of all operands to be equal to Result Type"));
  3044. }
  3045. TEST_P(ValidateOpenCLStdUMul24Like, U64Operand2) {
  3046. const std::string ext_inst_name = GetParam();
  3047. const std::string body =
  3048. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n";
  3049. CompileSuccessfully(GenerateKernelCode(body));
  3050. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3051. EXPECT_THAT(
  3052. getDiagnosticString(),
  3053. HasSubstr("OpenCL.std " + ext_inst_name +
  3054. ": expected types of all operands to be equal to Result Type"));
  3055. }
  3056. INSTANTIATE_TEST_SUITE_P(AllUMul24Like, ValidateOpenCLStdUMul24Like,
  3057. ::testing::ValuesIn(std::vector<std::string>{
  3058. "s_mul24",
  3059. "u_mul24",
  3060. }));
  3061. TEST_P(ValidateOpenCLStdUMad24Like, Success) {
  3062. const std::string ext_inst_name = GetParam();
  3063. std::ostringstream ss;
  3064. ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
  3065. << " %u32_0 %u32_1 %u32_2\n";
  3066. ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
  3067. << " %u32_0 %u32_1 %u32_2\n";
  3068. ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
  3069. << " %u32_0 %u32_1 %u32_2\n";
  3070. ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
  3071. << " %u32_0 %u32_1 %u32_2\n";
  3072. ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  3073. << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
  3074. ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  3075. << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
  3076. ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  3077. << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
  3078. ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
  3079. << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
  3080. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3081. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3082. }
  3083. TEST_P(ValidateOpenCLStdUMad24Like, FloatResultType) {
  3084. const std::string ext_inst_name = GetParam();
  3085. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  3086. " %u32_0 %u32_0 %u32_1\n";
  3087. CompileSuccessfully(GenerateKernelCode(body));
  3088. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3089. EXPECT_THAT(
  3090. getDiagnosticString(),
  3091. HasSubstr(
  3092. "OpenCL.std " + ext_inst_name +
  3093. ": expected Result Type to be a 32-bit int scalar or vector type"));
  3094. }
  3095. TEST_P(ValidateOpenCLStdUMad24Like, U64ResultType) {
  3096. const std::string ext_inst_name = GetParam();
  3097. const std::string body = "%val1 = OpExtInst %u64 %extinst " + ext_inst_name +
  3098. " %u64_0 %u64_0 %u64_1\n";
  3099. CompileSuccessfully(GenerateKernelCode(body));
  3100. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3101. EXPECT_THAT(
  3102. getDiagnosticString(),
  3103. HasSubstr(
  3104. "OpenCL.std " + ext_inst_name +
  3105. ": expected Result Type to be a 32-bit int scalar or vector type"));
  3106. }
  3107. TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand1) {
  3108. const std::string ext_inst_name = GetParam();
  3109. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  3110. " %f32_0 %u32_0 %u32_1\n";
  3111. CompileSuccessfully(GenerateKernelCode(body));
  3112. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3113. EXPECT_THAT(
  3114. getDiagnosticString(),
  3115. HasSubstr("OpenCL.std " + ext_inst_name +
  3116. ": expected types of all operands to be equal to Result Type"));
  3117. }
  3118. TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand2) {
  3119. const std::string ext_inst_name = GetParam();
  3120. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  3121. " %u32_0 %f32_0 %u32_1\n";
  3122. CompileSuccessfully(GenerateKernelCode(body));
  3123. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3124. EXPECT_THAT(
  3125. getDiagnosticString(),
  3126. HasSubstr("OpenCL.std " + ext_inst_name +
  3127. ": expected types of all operands to be equal to Result Type"));
  3128. }
  3129. TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand3) {
  3130. const std::string ext_inst_name = GetParam();
  3131. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  3132. " %u32_0 %u32_0 %f32_1\n";
  3133. CompileSuccessfully(GenerateKernelCode(body));
  3134. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3135. EXPECT_THAT(
  3136. getDiagnosticString(),
  3137. HasSubstr("OpenCL.std " + ext_inst_name +
  3138. ": expected types of all operands to be equal to Result Type"));
  3139. }
  3140. TEST_P(ValidateOpenCLStdUMad24Like, U64Operand1) {
  3141. const std::string ext_inst_name = GetParam();
  3142. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  3143. " %f32_0 %u32_0 %u64_1\n";
  3144. CompileSuccessfully(GenerateKernelCode(body));
  3145. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3146. EXPECT_THAT(
  3147. getDiagnosticString(),
  3148. HasSubstr("OpenCL.std " + ext_inst_name +
  3149. ": expected types of all operands to be equal to Result Type"));
  3150. }
  3151. TEST_P(ValidateOpenCLStdUMad24Like, U64Operand2) {
  3152. const std::string ext_inst_name = GetParam();
  3153. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  3154. " %u32_0 %f32_0 %u64_1\n";
  3155. CompileSuccessfully(GenerateKernelCode(body));
  3156. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3157. EXPECT_THAT(
  3158. getDiagnosticString(),
  3159. HasSubstr("OpenCL.std " + ext_inst_name +
  3160. ": expected types of all operands to be equal to Result Type"));
  3161. }
  3162. TEST_P(ValidateOpenCLStdUMad24Like, U64Operand3) {
  3163. const std::string ext_inst_name = GetParam();
  3164. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  3165. " %u32_0 %u32_0 %u64_1\n";
  3166. CompileSuccessfully(GenerateKernelCode(body));
  3167. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3168. EXPECT_THAT(
  3169. getDiagnosticString(),
  3170. HasSubstr("OpenCL.std " + ext_inst_name +
  3171. ": expected types of all operands to be equal to Result Type"));
  3172. }
  3173. INSTANTIATE_TEST_SUITE_P(AllUMad24Like, ValidateOpenCLStdUMad24Like,
  3174. ::testing::ValuesIn(std::vector<std::string>{
  3175. "s_mad24",
  3176. "u_mad24",
  3177. }));
  3178. TEST_F(ValidateExtInst, OpenCLStdCrossSuccess) {
  3179. const std::string body = R"(
  3180. %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_012 %f32vec3_123
  3181. %val2 = OpExtInst %f32vec4 %extinst cross %f32vec4_0123 %f32vec4_0123
  3182. )";
  3183. CompileSuccessfully(GenerateKernelCode(body));
  3184. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3185. }
  3186. TEST_F(ValidateExtInst, OpenCLStdCrossIntVectorResultType) {
  3187. const std::string body = R"(
  3188. %val1 = OpExtInst %u32vec3 %extinst cross %f32vec3_012 %f32vec3_123
  3189. )";
  3190. CompileSuccessfully(GenerateKernelCode(body));
  3191. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3192. EXPECT_THAT(getDiagnosticString(),
  3193. HasSubstr("OpenCL.std cross: "
  3194. "expected Result Type to be a float vector type"));
  3195. }
  3196. TEST_F(ValidateExtInst, OpenCLStdCrossResultTypeWrongSize) {
  3197. const std::string body = R"(
  3198. %val1 = OpExtInst %f32vec2 %extinst cross %f32vec3_012 %f32vec3_123
  3199. )";
  3200. CompileSuccessfully(GenerateKernelCode(body));
  3201. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3202. EXPECT_THAT(getDiagnosticString(),
  3203. HasSubstr("OpenCL.std cross: "
  3204. "expected Result Type to have 3 or 4 components"));
  3205. }
  3206. TEST_F(ValidateExtInst, OpenCLStdCrossXWrongType) {
  3207. const std::string body = R"(
  3208. %val1 = OpExtInst %f32vec3 %extinst cross %f64vec3_012 %f32vec3_123
  3209. )";
  3210. CompileSuccessfully(GenerateKernelCode(body));
  3211. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3212. EXPECT_THAT(getDiagnosticString(),
  3213. HasSubstr("OpenCL.std cross: "
  3214. "expected operand X type to be equal to Result Type"));
  3215. }
  3216. TEST_F(ValidateExtInst, OpenCLStdCrossYWrongType) {
  3217. const std::string body = R"(
  3218. %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_123 %f64vec3_012
  3219. )";
  3220. CompileSuccessfully(GenerateKernelCode(body));
  3221. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3222. EXPECT_THAT(getDiagnosticString(),
  3223. HasSubstr("OpenCL.std cross: "
  3224. "expected operand Y type to be equal to Result Type"));
  3225. }
  3226. TEST_P(ValidateOpenCLStdLengthLike, Success) {
  3227. const std::string ext_inst_name = GetParam();
  3228. std::ostringstream ss;
  3229. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32vec2_01\n";
  3230. ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name
  3231. << " %f32vec4_0123\n";
  3232. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3233. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3234. }
  3235. TEST_P(ValidateOpenCLStdLengthLike, IntResultType) {
  3236. const std::string ext_inst_name = GetParam();
  3237. const std::string body =
  3238. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32vec2_01\n";
  3239. CompileSuccessfully(GenerateKernelCode(body));
  3240. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3241. EXPECT_THAT(getDiagnosticString(),
  3242. HasSubstr("OpenCL.std " + ext_inst_name +
  3243. ": "
  3244. "expected Result Type to be a float scalar type"));
  3245. }
  3246. TEST_P(ValidateOpenCLStdLengthLike, IntX) {
  3247. const std::string ext_inst_name = GetParam();
  3248. const std::string body =
  3249. "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32vec2_01\n";
  3250. CompileSuccessfully(GenerateKernelCode(body));
  3251. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3252. EXPECT_THAT(getDiagnosticString(),
  3253. HasSubstr("OpenCL.std " + ext_inst_name +
  3254. ": "
  3255. "expected operand P to be a float scalar or vector"));
  3256. }
  3257. TEST_P(ValidateOpenCLStdLengthLike, VectorTooBig) {
  3258. const std::string ext_inst_name = GetParam();
  3259. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  3260. " %f32vec8_01010101\n";
  3261. CompileSuccessfully(GenerateKernelCode(body));
  3262. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3263. EXPECT_THAT(
  3264. getDiagnosticString(),
  3265. HasSubstr("OpenCL.std " + ext_inst_name +
  3266. ": "
  3267. "expected operand P to have no more than 4 components"));
  3268. }
  3269. TEST_P(ValidateOpenCLStdLengthLike, DifferentType) {
  3270. const std::string ext_inst_name = GetParam();
  3271. const std::string body =
  3272. "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32vec2_01\n";
  3273. CompileSuccessfully(GenerateKernelCode(body));
  3274. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3275. EXPECT_THAT(getDiagnosticString(),
  3276. HasSubstr("OpenCL.std " + ext_inst_name +
  3277. ": "
  3278. "expected operand P component type to be equal to "
  3279. "Result Type"));
  3280. }
  3281. INSTANTIATE_TEST_SUITE_P(AllLengthLike, ValidateOpenCLStdLengthLike,
  3282. ::testing::ValuesIn(std::vector<std::string>{
  3283. "length",
  3284. "fast_length",
  3285. }));
  3286. TEST_P(ValidateOpenCLStdDistanceLike, Success) {
  3287. const std::string ext_inst_name = GetParam();
  3288. std::ostringstream ss;
  3289. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  3290. << " %f32vec2_01 %f32vec2_01\n";
  3291. ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name
  3292. << " %f32vec4_0123 %f32vec4_1234\n";
  3293. ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name
  3294. << " %f32_0 %f32_1\n";
  3295. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3296. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3297. }
  3298. TEST_P(ValidateOpenCLStdDistanceLike, IntResultType) {
  3299. const std::string ext_inst_name = GetParam();
  3300. const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
  3301. " %f32vec2_01 %f32vec2_12\n";
  3302. CompileSuccessfully(GenerateKernelCode(body));
  3303. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3304. EXPECT_THAT(getDiagnosticString(),
  3305. HasSubstr("OpenCL.std " + ext_inst_name +
  3306. ": "
  3307. "expected Result Type to be a float scalar type"));
  3308. }
  3309. TEST_P(ValidateOpenCLStdDistanceLike, IntP0) {
  3310. const std::string ext_inst_name = GetParam();
  3311. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  3312. " %u32vec2_01 %f32vec2_12\n";
  3313. CompileSuccessfully(GenerateKernelCode(body));
  3314. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3315. EXPECT_THAT(
  3316. getDiagnosticString(),
  3317. HasSubstr("OpenCL.std " + ext_inst_name +
  3318. ": "
  3319. "expected operand P0 to be of float scalar or vector type"));
  3320. }
  3321. TEST_P(ValidateOpenCLStdDistanceLike, VectorTooBig) {
  3322. const std::string ext_inst_name = GetParam();
  3323. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  3324. " %f32vec8_01010101 %f32vec8_01010101\n";
  3325. CompileSuccessfully(GenerateKernelCode(body));
  3326. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3327. EXPECT_THAT(
  3328. getDiagnosticString(),
  3329. HasSubstr("OpenCL.std " + ext_inst_name +
  3330. ": "
  3331. "expected operand P0 to have no more than 4 components"));
  3332. }
  3333. TEST_P(ValidateOpenCLStdDistanceLike, F64P0) {
  3334. const std::string ext_inst_name = GetParam();
  3335. const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
  3336. " %f64vec2_01 %f32vec2_12\n";
  3337. CompileSuccessfully(GenerateKernelCode(body));
  3338. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3339. EXPECT_THAT(
  3340. getDiagnosticString(),
  3341. HasSubstr(
  3342. "OpenCL.std " + ext_inst_name +
  3343. ": "
  3344. "expected operand P0 component type to be equal to Result Type"));
  3345. }
  3346. TEST_P(ValidateOpenCLStdDistanceLike, DifferentOperands) {
  3347. const std::string ext_inst_name = GetParam();
  3348. const std::string body = "%val1 = OpExtInst %f64 %extinst " + ext_inst_name +
  3349. " %f64vec2_01 %f32vec2_12\n";
  3350. CompileSuccessfully(GenerateKernelCode(body));
  3351. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3352. EXPECT_THAT(getDiagnosticString(),
  3353. HasSubstr("OpenCL.std " + ext_inst_name +
  3354. ": "
  3355. "expected operands P0 and P1 to be of the same type"));
  3356. }
  3357. INSTANTIATE_TEST_SUITE_P(AllDistanceLike, ValidateOpenCLStdDistanceLike,
  3358. ::testing::ValuesIn(std::vector<std::string>{
  3359. "distance",
  3360. "fast_distance",
  3361. }));
  3362. TEST_P(ValidateOpenCLStdNormalizeLike, Success) {
  3363. const std::string ext_inst_name = GetParam();
  3364. std::ostringstream ss;
  3365. ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  3366. << " %f32vec2_01\n";
  3367. ss << "%val2 = OpExtInst %f32vec4 %extinst " << ext_inst_name
  3368. << " %f32vec4_0123\n";
  3369. ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_2\n";
  3370. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3371. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3372. }
  3373. TEST_P(ValidateOpenCLStdNormalizeLike, IntResultType) {
  3374. const std::string ext_inst_name = GetParam();
  3375. const std::string body =
  3376. "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_2\n";
  3377. CompileSuccessfully(GenerateKernelCode(body));
  3378. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3379. EXPECT_THAT(
  3380. getDiagnosticString(),
  3381. HasSubstr("OpenCL.std " + ext_inst_name +
  3382. ": "
  3383. "expected Result Type to be a float scalar or vector type"));
  3384. }
  3385. TEST_P(ValidateOpenCLStdNormalizeLike, VectorTooBig) {
  3386. const std::string ext_inst_name = GetParam();
  3387. const std::string body = "%val1 = OpExtInst %f32vec8 %extinst " +
  3388. ext_inst_name + " %f32vec8_01010101\n";
  3389. CompileSuccessfully(GenerateKernelCode(body));
  3390. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3391. EXPECT_THAT(
  3392. getDiagnosticString(),
  3393. HasSubstr("OpenCL.std " + ext_inst_name +
  3394. ": "
  3395. "expected Result Type to have no more than 4 components"));
  3396. }
  3397. TEST_P(ValidateOpenCLStdNormalizeLike, DifferentType) {
  3398. const std::string ext_inst_name = GetParam();
  3399. const std::string body =
  3400. "%val1 = OpExtInst %f64vec2 %extinst " + ext_inst_name + " %f32vec2_01\n";
  3401. CompileSuccessfully(GenerateKernelCode(body));
  3402. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3403. EXPECT_THAT(getDiagnosticString(),
  3404. HasSubstr("OpenCL.std " + ext_inst_name +
  3405. ": "
  3406. "expected operand P type to be equal to Result Type"));
  3407. }
  3408. INSTANTIATE_TEST_SUITE_P(AllNormalizeLike, ValidateOpenCLStdNormalizeLike,
  3409. ::testing::ValuesIn(std::vector<std::string>{
  3410. "normalize",
  3411. "fast_normalize",
  3412. }));
  3413. TEST_F(ValidateExtInst, OpenCLStdBitselectSuccess) {
  3414. const std::string body = R"(
  3415. %val1 = OpExtInst %f32 %extinst bitselect %f32_2 %f32_1 %f32_1
  3416. %val2 = OpExtInst %f32vec4 %extinst bitselect %f32vec4_0123 %f32vec4_1234 %f32vec4_0123
  3417. %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %u32_1
  3418. %val4 = OpExtInst %u32vec4 %extinst bitselect %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
  3419. %val5 = OpExtInst %u64 %extinst bitselect %u64_2 %u64_1 %u64_1
  3420. )";
  3421. CompileSuccessfully(GenerateKernelCode(body));
  3422. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3423. }
  3424. TEST_F(ValidateExtInst, OpenCLStdBitselectWrongResultType) {
  3425. const std::string body = R"(
  3426. %val3 = OpExtInst %struct_f32_f32 %extinst bitselect %u32_2 %u32_1 %u32_1
  3427. )";
  3428. CompileSuccessfully(GenerateKernelCode(body));
  3429. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3430. EXPECT_THAT(
  3431. getDiagnosticString(),
  3432. HasSubstr(
  3433. "OpenCL.std bitselect: "
  3434. "expected Result Type to be an int or float scalar or vector type"));
  3435. }
  3436. TEST_F(ValidateExtInst, OpenCLStdBitselectAWrongType) {
  3437. const std::string body = R"(
  3438. %val3 = OpExtInst %u32 %extinst bitselect %f32_2 %u32_1 %u32_1
  3439. )";
  3440. CompileSuccessfully(GenerateKernelCode(body));
  3441. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3442. EXPECT_THAT(
  3443. getDiagnosticString(),
  3444. HasSubstr("OpenCL.std bitselect: "
  3445. "expected types of all operands to be equal to Result Type"));
  3446. }
  3447. TEST_F(ValidateExtInst, OpenCLStdBitselectBWrongType) {
  3448. const std::string body = R"(
  3449. %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %f32_1 %u32_1
  3450. )";
  3451. CompileSuccessfully(GenerateKernelCode(body));
  3452. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3453. EXPECT_THAT(
  3454. getDiagnosticString(),
  3455. HasSubstr("OpenCL.std bitselect: "
  3456. "expected types of all operands to be equal to Result Type"));
  3457. }
  3458. TEST_F(ValidateExtInst, OpenCLStdBitselectCWrongType) {
  3459. const std::string body = R"(
  3460. %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %f32_1
  3461. )";
  3462. CompileSuccessfully(GenerateKernelCode(body));
  3463. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3464. EXPECT_THAT(
  3465. getDiagnosticString(),
  3466. HasSubstr("OpenCL.std bitselect: "
  3467. "expected types of all operands to be equal to Result Type"));
  3468. }
  3469. TEST_F(ValidateExtInst, OpenCLStdSelectSuccess) {
  3470. const std::string body = R"(
  3471. %val1 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %u32_1
  3472. %val2 = OpExtInst %f32vec4 %extinst select %f32vec4_0123 %f32vec4_1234 %u32vec4_0123
  3473. %val3 = OpExtInst %u32 %extinst select %u32_2 %u32_1 %u32_1
  3474. %val4 = OpExtInst %u32vec4 %extinst select %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
  3475. %val5 = OpExtInst %u64 %extinst select %u64_2 %u64_1 %u64_1
  3476. )";
  3477. CompileSuccessfully(GenerateKernelCode(body));
  3478. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3479. }
  3480. TEST_F(ValidateExtInst, OpenCLStdSelectWrongResultType) {
  3481. const std::string body = R"(
  3482. %val3 = OpExtInst %struct_f32_f32 %extinst select %u32_2 %u32_1 %u32_1
  3483. )";
  3484. CompileSuccessfully(GenerateKernelCode(body));
  3485. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3486. EXPECT_THAT(
  3487. getDiagnosticString(),
  3488. HasSubstr(
  3489. "OpenCL.std select: "
  3490. "expected Result Type to be an int or float scalar or vector type"));
  3491. }
  3492. TEST_F(ValidateExtInst, OpenCLStdSelectAWrongType) {
  3493. const std::string body = R"(
  3494. %val3 = OpExtInst %u32 %extinst select %f32_2 %u32_1 %u32_1
  3495. )";
  3496. CompileSuccessfully(GenerateKernelCode(body));
  3497. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3498. EXPECT_THAT(getDiagnosticString(),
  3499. HasSubstr("OpenCL.std select: "
  3500. "expected operand A type to be equal to Result Type"));
  3501. }
  3502. TEST_F(ValidateExtInst, OpenCLStdSelectBWrongType) {
  3503. const std::string body = R"(
  3504. %val3 = OpExtInst %u32 %extinst select %u32_2 %f32_1 %u32_1
  3505. )";
  3506. CompileSuccessfully(GenerateKernelCode(body));
  3507. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3508. EXPECT_THAT(getDiagnosticString(),
  3509. HasSubstr("OpenCL.std select: "
  3510. "expected operand B type to be equal to Result Type"));
  3511. }
  3512. TEST_F(ValidateExtInst, OpenCLStdSelectCWrongType) {
  3513. const std::string body = R"(
  3514. %val3 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %f32_1
  3515. )";
  3516. CompileSuccessfully(GenerateKernelCode(body));
  3517. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3518. EXPECT_THAT(getDiagnosticString(),
  3519. HasSubstr("OpenCL.std select: "
  3520. "expected operand C to be an int scalar or vector"));
  3521. }
  3522. TEST_F(ValidateExtInst, OpenCLStdSelectCWrongComponentNumber) {
  3523. const std::string body = R"(
  3524. %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u32_1
  3525. )";
  3526. CompileSuccessfully(GenerateKernelCode(body));
  3527. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3528. EXPECT_THAT(getDiagnosticString(),
  3529. HasSubstr("OpenCL.std select: "
  3530. "expected operand C to have the same number of "
  3531. "components as Result Type"));
  3532. }
  3533. TEST_F(ValidateExtInst, OpenCLStdSelectCWrongBitWidth) {
  3534. const std::string body = R"(
  3535. %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u64vec2_01
  3536. )";
  3537. CompileSuccessfully(GenerateKernelCode(body));
  3538. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3539. EXPECT_THAT(
  3540. getDiagnosticString(),
  3541. HasSubstr(
  3542. "OpenCL.std select: "
  3543. "expected operand C to have the same bit width as Result Type"));
  3544. }
  3545. TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical32) {
  3546. const std::string ext_inst_name = GetParam();
  3547. const std::string rounding_mode =
  3548. ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
  3549. std::ostringstream ss;
  3550. ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
  3551. if (std::string::npos == ext_inst_name.find("halfn")) {
  3552. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3553. << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n";
  3554. ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
  3555. << " %f64_0 %u32_2 %ptr" << rounding_mode << "\n";
  3556. } else {
  3557. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3558. << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
  3559. ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
  3560. << " %f32vec4_0123 %u32_0 %ptr" << rounding_mode << "\n";
  3561. ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name
  3562. << " %f64vec2_01 %u32_2 %ptr" << rounding_mode << "\n";
  3563. }
  3564. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3565. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3566. }
  3567. TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical64) {
  3568. const std::string ext_inst_name = GetParam();
  3569. const std::string rounding_mode =
  3570. ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
  3571. std::ostringstream ss;
  3572. ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
  3573. if (std::string::npos == ext_inst_name.find("halfn")) {
  3574. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3575. << " %f32_1 %u64_1 %ptr" << rounding_mode << "\n";
  3576. ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
  3577. << " %f64_0 %u64_2 %ptr" << rounding_mode << "\n";
  3578. } else {
  3579. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3580. << " %f32vec2_01 %u64_1 %ptr" << rounding_mode << "\n";
  3581. ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
  3582. << " %f32vec4_0123 %u64_0 %ptr" << rounding_mode << "\n";
  3583. ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name
  3584. << " %f64vec2_01 %u64_2 %ptr" << rounding_mode << "\n";
  3585. }
  3586. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
  3587. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3588. }
  3589. TEST_P(ValidateOpenCLStdVStoreHalfLike, NonVoidResultType) {
  3590. const std::string ext_inst_name = GetParam();
  3591. const std::string rounding_mode =
  3592. ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
  3593. std::ostringstream ss;
  3594. ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
  3595. if (std::string::npos == ext_inst_name.find("halfn")) {
  3596. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  3597. << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n";
  3598. } else {
  3599. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  3600. << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
  3601. }
  3602. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3603. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3604. EXPECT_THAT(getDiagnosticString(),
  3605. HasSubstr("OpenCL.std " + ext_inst_name +
  3606. ": expected Result Type to be void"));
  3607. }
  3608. TEST_P(ValidateOpenCLStdVStoreHalfLike, WrongDataType) {
  3609. const std::string ext_inst_name = GetParam();
  3610. const std::string rounding_mode =
  3611. ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
  3612. std::ostringstream ss;
  3613. ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
  3614. if (std::string::npos == ext_inst_name.find("halfn")) {
  3615. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3616. << " %f64vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
  3617. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3618. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3619. EXPECT_THAT(getDiagnosticString(),
  3620. HasSubstr("OpenCL.std " + ext_inst_name +
  3621. ": expected Data to be a 32 or 64-bit float scalar"));
  3622. } else {
  3623. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3624. << " %f64_0 %u32_1 %ptr" << rounding_mode << "\n";
  3625. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3626. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3627. EXPECT_THAT(getDiagnosticString(),
  3628. HasSubstr("OpenCL.std " + ext_inst_name +
  3629. ": expected Data to be a 32 or 64-bit float vector"));
  3630. }
  3631. }
  3632. TEST_P(ValidateOpenCLStdVStoreHalfLike, AddressingModelLogical) {
  3633. const std::string ext_inst_name = GetParam();
  3634. const std::string rounding_mode =
  3635. ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
  3636. std::ostringstream ss;
  3637. ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
  3638. if (std::string::npos == ext_inst_name.find("halfn")) {
  3639. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3640. << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
  3641. } else {
  3642. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3643. << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
  3644. }
  3645. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
  3646. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3647. EXPECT_THAT(getDiagnosticString(),
  3648. HasSubstr("OpenCL.std " + ext_inst_name +
  3649. " can only be used with physical addressing models"));
  3650. }
  3651. TEST_P(ValidateOpenCLStdVStoreHalfLike, OffsetNotSizeT) {
  3652. const std::string ext_inst_name = GetParam();
  3653. const std::string rounding_mode =
  3654. ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
  3655. std::ostringstream ss;
  3656. ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
  3657. if (std::string::npos == ext_inst_name.find("halfn")) {
  3658. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3659. << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
  3660. } else {
  3661. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3662. << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
  3663. }
  3664. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
  3665. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3666. EXPECT_THAT(
  3667. getDiagnosticString(),
  3668. HasSubstr("OpenCL.std " + ext_inst_name +
  3669. ": "
  3670. "expected operand Offset to be of type size_t (64-bit integer "
  3671. "for the addressing model used in the module)"));
  3672. }
  3673. TEST_P(ValidateOpenCLStdVStoreHalfLike, PNotPointer) {
  3674. const std::string ext_inst_name = GetParam();
  3675. const std::string rounding_mode =
  3676. ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
  3677. std::ostringstream ss;
  3678. if (std::string::npos == ext_inst_name.find("halfn")) {
  3679. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3680. << " %f32_0 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n";
  3681. } else {
  3682. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3683. << " %f32vec2_01 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n";
  3684. }
  3685. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3686. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3687. EXPECT_THAT(getDiagnosticString(),
  3688. HasSubstr("Operand '89[%_ptr_Workgroup_half]' cannot be a type"));
  3689. }
  3690. TEST_P(ValidateOpenCLStdVStoreHalfLike, ConstPointer) {
  3691. const std::string ext_inst_name = GetParam();
  3692. const std::string rounding_mode =
  3693. ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
  3694. std::ostringstream ss;
  3695. ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
  3696. "%f16vec8_uniform_constant %u32_1\n";
  3697. if (std::string::npos == ext_inst_name.find("halfn")) {
  3698. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3699. << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
  3700. } else {
  3701. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3702. << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
  3703. }
  3704. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3705. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3706. EXPECT_THAT(getDiagnosticString(),
  3707. HasSubstr("OpenCL.std " + ext_inst_name +
  3708. ": expected operand P storage class to be Generic, "
  3709. "CrossWorkgroup, Workgroup or Function"));
  3710. }
  3711. TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeInt) {
  3712. const std::string ext_inst_name = GetParam();
  3713. const std::string rounding_mode =
  3714. ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
  3715. std::ostringstream ss;
  3716. ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
  3717. if (std::string::npos == ext_inst_name.find("halfn")) {
  3718. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3719. << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
  3720. } else {
  3721. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3722. << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
  3723. }
  3724. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3725. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3726. EXPECT_THAT(
  3727. getDiagnosticString(),
  3728. HasSubstr("OpenCL.std " + ext_inst_name +
  3729. ": expected operand P data type to be 16-bit float scalar"));
  3730. }
  3731. TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeFloat32) {
  3732. const std::string ext_inst_name = GetParam();
  3733. const std::string rounding_mode =
  3734. ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
  3735. std::ostringstream ss;
  3736. ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
  3737. if (std::string::npos == ext_inst_name.find("halfn")) {
  3738. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3739. << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
  3740. } else {
  3741. ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
  3742. << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
  3743. }
  3744. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3745. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3746. EXPECT_THAT(
  3747. getDiagnosticString(),
  3748. HasSubstr("OpenCL.std " + ext_inst_name +
  3749. ": expected operand P data type to be 16-bit float scalar"));
  3750. }
  3751. INSTANTIATE_TEST_SUITE_P(AllVStoreHalfLike, ValidateOpenCLStdVStoreHalfLike,
  3752. ::testing::ValuesIn(std::vector<std::string>{
  3753. "vstore_half",
  3754. "vstore_half_r",
  3755. "vstore_halfn",
  3756. "vstore_halfn_r",
  3757. "vstorea_halfn",
  3758. "vstorea_halfn_r",
  3759. }));
  3760. TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical32) {
  3761. const std::string ext_inst_name = GetParam();
  3762. std::ostringstream ss;
  3763. ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
  3764. ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  3765. << " %u32_1 %ptr 2\n";
  3766. ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name
  3767. << " %u32_1 %ptr 3\n";
  3768. ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
  3769. << " %u32_1 %ptr 4\n";
  3770. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3771. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3772. }
  3773. TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical64) {
  3774. const std::string ext_inst_name = GetParam();
  3775. std::ostringstream ss;
  3776. ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
  3777. ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  3778. << " %u64_1 %ptr 2\n";
  3779. ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name
  3780. << " %u64_1 %ptr 3\n";
  3781. ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
  3782. << " %u64_1 %ptr 4\n";
  3783. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
  3784. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3785. }
  3786. TEST_P(ValidateOpenCLStdVLoadHalfLike, ResultTypeNotFloatVector) {
  3787. const std::string ext_inst_name = GetParam();
  3788. std::ostringstream ss;
  3789. ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
  3790. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  3791. << " %u32_1 %ptr 1\n";
  3792. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3793. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3794. EXPECT_THAT(getDiagnosticString(),
  3795. HasSubstr("OpenCL.std " + ext_inst_name +
  3796. ": expected Result Type to be a float vector type"));
  3797. }
  3798. TEST_P(ValidateOpenCLStdVLoadHalfLike, AddressingModelLogical) {
  3799. const std::string ext_inst_name = GetParam();
  3800. std::ostringstream ss;
  3801. ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
  3802. ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  3803. << " %u32_1 %ptr 2\n";
  3804. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
  3805. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3806. EXPECT_THAT(getDiagnosticString(),
  3807. HasSubstr("OpenCL.std " + ext_inst_name +
  3808. " can only be used with physical addressing models"));
  3809. }
  3810. TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetNotSizeT) {
  3811. const std::string ext_inst_name = GetParam();
  3812. std::ostringstream ss;
  3813. ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
  3814. ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  3815. << " %u64_1 %ptr 2\n";
  3816. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3817. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3818. EXPECT_THAT(
  3819. getDiagnosticString(),
  3820. HasSubstr("OpenCL.std " + ext_inst_name +
  3821. ": expected operand Offset to be of type size_t (32-bit "
  3822. "integer for the addressing model used in the module)"));
  3823. }
  3824. TEST_P(ValidateOpenCLStdVLoadHalfLike, PNotPointer) {
  3825. const std::string ext_inst_name = GetParam();
  3826. std::ostringstream ss;
  3827. ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  3828. << " %u32_1 %f16_ptr_workgroup 2\n";
  3829. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3830. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3831. EXPECT_THAT(getDiagnosticString(),
  3832. HasSubstr("Operand '89[%_ptr_Workgroup_half]' cannot be a type"));
  3833. }
  3834. TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetWrongStorageType) {
  3835. const std::string ext_inst_name = GetParam();
  3836. std::ostringstream ss;
  3837. ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
  3838. ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  3839. << " %u32_1 %ptr 2\n";
  3840. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3841. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3842. EXPECT_THAT(
  3843. getDiagnosticString(),
  3844. HasSubstr("OpenCL.std " + ext_inst_name +
  3845. ": expected operand P storage class to be UniformConstant, "
  3846. "Generic, CrossWorkgroup, Workgroup or Function"));
  3847. }
  3848. TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeInt) {
  3849. const std::string ext_inst_name = GetParam();
  3850. std::ostringstream ss;
  3851. ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
  3852. ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  3853. << " %u32_1 %ptr 2\n";
  3854. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3855. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3856. EXPECT_THAT(
  3857. getDiagnosticString(),
  3858. HasSubstr("OpenCL.std " + ext_inst_name +
  3859. ": expected operand P data type to be 16-bit float scalar"));
  3860. }
  3861. TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeFloat32) {
  3862. const std::string ext_inst_name = GetParam();
  3863. std::ostringstream ss;
  3864. ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
  3865. ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  3866. << " %u32_1 %ptr 2\n";
  3867. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3868. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3869. EXPECT_THAT(
  3870. getDiagnosticString(),
  3871. HasSubstr("OpenCL.std " + ext_inst_name +
  3872. ": expected operand P data type to be 16-bit float scalar"));
  3873. }
  3874. TEST_P(ValidateOpenCLStdVLoadHalfLike, WrongN) {
  3875. const std::string ext_inst_name = GetParam();
  3876. std::ostringstream ss;
  3877. ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
  3878. ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  3879. << " %u32_1 %ptr 3\n";
  3880. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3881. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3882. EXPECT_THAT(getDiagnosticString(),
  3883. HasSubstr("OpenCL.std " + ext_inst_name +
  3884. ": expected literal N to be equal to the number of "
  3885. "components of Result Type"));
  3886. }
  3887. INSTANTIATE_TEST_SUITE_P(AllVLoadHalfLike, ValidateOpenCLStdVLoadHalfLike,
  3888. ::testing::ValuesIn(std::vector<std::string>{
  3889. "vload_halfn",
  3890. "vloada_halfn",
  3891. }));
  3892. TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical32) {
  3893. std::ostringstream ss;
  3894. ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
  3895. "%f32vec8_uniform_constant %u32_1\n";
  3896. ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n";
  3897. ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u32_1 %ptr 3\n";
  3898. ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u32_1 %ptr 4\n";
  3899. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3900. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3901. }
  3902. TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical32) {
  3903. std::ostringstream ss;
  3904. ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
  3905. "%u32vec8_uniform_constant %u32_1\n";
  3906. ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
  3907. ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u32_1 %ptr 3\n";
  3908. ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u32_1 %ptr 4\n";
  3909. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3910. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3911. }
  3912. TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical64) {
  3913. std::ostringstream ss;
  3914. ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
  3915. "%f32vec8_uniform_constant %u32_1\n";
  3916. ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n";
  3917. ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u64_1 %ptr 3\n";
  3918. ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u64_1 %ptr 4\n";
  3919. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
  3920. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3921. }
  3922. TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical64) {
  3923. std::ostringstream ss;
  3924. ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
  3925. "%u32vec8_uniform_constant %u32_1\n";
  3926. ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u64_1 %ptr 2\n";
  3927. ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u64_1 %ptr 3\n";
  3928. ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u64_1 %ptr 4\n";
  3929. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
  3930. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  3931. }
  3932. TEST_F(ValidateExtInst, VLoadNWrongResultType) {
  3933. std::ostringstream ss;
  3934. ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
  3935. "%f32vec8_uniform_constant %u32_1\n";
  3936. ss << "%val1 = OpExtInst %f32 %extinst vloadn %u32_1 %ptr 2\n";
  3937. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3938. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3939. EXPECT_THAT(
  3940. getDiagnosticString(),
  3941. HasSubstr("OpenCL.std vloadn: "
  3942. "expected Result Type to be an int or float vector type"));
  3943. }
  3944. TEST_F(ValidateExtInst, VLoadNAddressingModelLogical) {
  3945. std::ostringstream ss;
  3946. ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
  3947. "%f32vec8_uniform_constant %u32_1\n";
  3948. ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n";
  3949. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
  3950. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3951. EXPECT_THAT(getDiagnosticString(),
  3952. HasSubstr("OpenCL.std vloadn can only be used with physical "
  3953. "addressing models"));
  3954. }
  3955. TEST_F(ValidateExtInst, VLoadNOffsetNotSizeT) {
  3956. std::ostringstream ss;
  3957. ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
  3958. "%f32vec8_uniform_constant %u32_1\n";
  3959. ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n";
  3960. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3961. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3962. EXPECT_THAT(
  3963. getDiagnosticString(),
  3964. HasSubstr(
  3965. "OpenCL.std vloadn: expected operand Offset to be of type size_t "
  3966. "(32-bit integer for the addressing model used in the module)"));
  3967. }
  3968. TEST_F(ValidateExtInst, VLoadNPNotPointer) {
  3969. std::ostringstream ss;
  3970. ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 "
  3971. "%f32_ptr_uniform_constant 2\n";
  3972. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3973. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  3974. EXPECT_THAT(
  3975. getDiagnosticString(),
  3976. HasSubstr("Operand '120[%_ptr_UniformConstant_float]' cannot be a "
  3977. "type"));
  3978. }
  3979. TEST_F(ValidateExtInst, VLoadNWrongStorageClass) {
  3980. std::ostringstream ss;
  3981. ss << "%ptr = OpAccessChain %u32_ptr_input %u32vec8_input %u32_1\n";
  3982. ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
  3983. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3984. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3985. EXPECT_THAT(getDiagnosticString(),
  3986. HasSubstr("OpenCL.std vloadn: expected operand P storage class "
  3987. "to be UniformConstant, Generic, CrossWorkgroup, "
  3988. "Workgroup or Function"));
  3989. }
  3990. TEST_F(ValidateExtInst, VLoadNWrongComponentType) {
  3991. std::ostringstream ss;
  3992. ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
  3993. "%f32vec8_uniform_constant %u32_1\n";
  3994. ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
  3995. CompileSuccessfully(GenerateKernelCode(ss.str()));
  3996. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  3997. EXPECT_THAT(getDiagnosticString(),
  3998. HasSubstr("OpenCL.std vloadn: expected operand P data type to be "
  3999. "equal to component type of Result Type"));
  4000. }
  4001. TEST_F(ValidateExtInst, VLoadNWrongN) {
  4002. std::ostringstream ss;
  4003. ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
  4004. "%f32vec8_uniform_constant %u32_1\n";
  4005. ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 3\n";
  4006. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4007. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4008. EXPECT_THAT(getDiagnosticString(),
  4009. HasSubstr("OpenCL.std vloadn: expected literal N to be equal to "
  4010. "the number of components of Result Type"));
  4011. }
  4012. TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical32) {
  4013. std::ostringstream ss;
  4014. ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
  4015. "%f16vec8_uniform_constant %u32_1\n";
  4016. ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
  4017. ss << "%val2 = OpExtInst %f64 %extinst vload_half %u32_1 %ptr\n";
  4018. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4019. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4020. }
  4021. TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical64) {
  4022. std::ostringstream ss;
  4023. ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
  4024. "%f16vec8_uniform_constant %u32_1\n";
  4025. ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
  4026. ss << "%val2 = OpExtInst %f64 %extinst vload_half %u64_1 %ptr\n";
  4027. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
  4028. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4029. }
  4030. TEST_F(ValidateExtInst, VLoadHalfWrongResultType) {
  4031. std::ostringstream ss;
  4032. ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
  4033. "%f16vec8_uniform_constant %u32_1\n";
  4034. ss << "%val1 = OpExtInst %u32 %extinst vload_half %u32_1 %ptr\n";
  4035. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4036. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4037. EXPECT_THAT(getDiagnosticString(),
  4038. HasSubstr("OpenCL.std vload_half: "
  4039. "expected Result Type to be a float scalar type"));
  4040. }
  4041. TEST_F(ValidateExtInst, VLoadHalfAddressingModelLogical) {
  4042. std::ostringstream ss;
  4043. ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
  4044. "%f16vec8_uniform_constant %u32_1\n";
  4045. ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
  4046. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
  4047. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4048. EXPECT_THAT(getDiagnosticString(),
  4049. HasSubstr("OpenCL.std vload_half can only be used with physical "
  4050. "addressing models"));
  4051. }
  4052. TEST_F(ValidateExtInst, VLoadHalfOffsetNotSizeT) {
  4053. std::ostringstream ss;
  4054. ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
  4055. "%f16vec8_uniform_constant %u32_1\n";
  4056. ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
  4057. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4058. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4059. EXPECT_THAT(
  4060. getDiagnosticString(),
  4061. HasSubstr(
  4062. "OpenCL.std vload_half: expected operand Offset to be of type size_t "
  4063. "(32-bit integer for the addressing model used in the module)"));
  4064. }
  4065. TEST_F(ValidateExtInst, VLoadHalfPNotPointer) {
  4066. std::ostringstream ss;
  4067. ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 "
  4068. "%f16_ptr_uniform_constant\n";
  4069. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4070. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4071. EXPECT_THAT(getDiagnosticString(),
  4072. HasSubstr("Operand '114[%_ptr_UniformConstant_half]' cannot be a "
  4073. "type"));
  4074. }
  4075. TEST_F(ValidateExtInst, VLoadHalfWrongStorageClass) {
  4076. std::ostringstream ss;
  4077. ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
  4078. ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
  4079. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4080. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4081. EXPECT_THAT(
  4082. getDiagnosticString(),
  4083. HasSubstr(
  4084. "OpenCL.std vload_half: expected operand P storage class to be "
  4085. "UniformConstant, Generic, CrossWorkgroup, Workgroup or Function"));
  4086. }
  4087. TEST_F(ValidateExtInst, VLoadHalfPDataTypeInt) {
  4088. std::ostringstream ss;
  4089. ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
  4090. "%u32vec8_uniform_constant %u32_1\n";
  4091. ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
  4092. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4093. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4094. EXPECT_THAT(getDiagnosticString(),
  4095. HasSubstr("OpenCL.std vload_half: expected operand P data type "
  4096. "to be 16-bit float scalar"));
  4097. }
  4098. TEST_F(ValidateExtInst, VLoadHalfPDataTypeFloat32) {
  4099. std::ostringstream ss;
  4100. ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
  4101. "%f32vec8_uniform_constant %u32_1\n";
  4102. ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
  4103. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4104. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4105. EXPECT_THAT(getDiagnosticString(),
  4106. HasSubstr("OpenCL.std vload_half: expected operand P data type "
  4107. "to be 16-bit float scalar"));
  4108. }
  4109. TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical32) {
  4110. std::ostringstream ss;
  4111. ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
  4112. ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
  4113. ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
  4114. ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u32_1 "
  4115. "%ptr_g\n";
  4116. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4117. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4118. }
  4119. TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical64) {
  4120. std::ostringstream ss;
  4121. ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
  4122. ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
  4123. ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u64_1 %ptr_g\n";
  4124. ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u64_1 "
  4125. "%ptr_g\n";
  4126. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
  4127. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4128. }
  4129. TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical32) {
  4130. std::ostringstream ss;
  4131. ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
  4132. ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
  4133. ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
  4134. ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u32_1 "
  4135. "%ptr_g\n";
  4136. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4137. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4138. }
  4139. TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical64) {
  4140. std::ostringstream ss;
  4141. ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
  4142. ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
  4143. ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u64_1 %ptr_g\n";
  4144. ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u64_1 "
  4145. "%ptr_g\n";
  4146. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
  4147. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4148. }
  4149. TEST_F(ValidateExtInst, VStoreNResultTypeNotVoid) {
  4150. std::ostringstream ss;
  4151. ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
  4152. ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
  4153. ss << "%val1 = OpExtInst %f32 %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
  4154. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4155. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4156. EXPECT_THAT(getDiagnosticString(),
  4157. HasSubstr("OpenCL.std vstoren: expected Result Type to be void"));
  4158. }
  4159. TEST_F(ValidateExtInst, VStoreNDataWrongType) {
  4160. std::ostringstream ss;
  4161. ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
  4162. ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
  4163. ss << "%val1 = OpExtInst %void %extinst vstoren %f32_1 %u32_1 %ptr_g\n";
  4164. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4165. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4166. EXPECT_THAT(
  4167. getDiagnosticString(),
  4168. HasSubstr(
  4169. "OpenCL.std vstoren: expected Data to be an int or float vector"));
  4170. }
  4171. TEST_F(ValidateExtInst, VStoreNAddressingModelLogical) {
  4172. std::ostringstream ss;
  4173. ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
  4174. ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
  4175. ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
  4176. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
  4177. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4178. EXPECT_THAT(getDiagnosticString(),
  4179. HasSubstr("OpenCL.std vstoren can only be used with physical "
  4180. "addressing models"));
  4181. }
  4182. TEST_F(ValidateExtInst, VStoreNOffsetNotSizeT) {
  4183. std::ostringstream ss;
  4184. ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
  4185. ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
  4186. ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
  4187. CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
  4188. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4189. EXPECT_THAT(
  4190. getDiagnosticString(),
  4191. HasSubstr(
  4192. "OpenCL.std vstoren: expected operand Offset to be of type size_t "
  4193. "(64-bit integer for the addressing model used in the module)"));
  4194. }
  4195. TEST_F(ValidateExtInst, VStoreNPNotPointer) {
  4196. std::ostringstream ss;
  4197. ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 "
  4198. "%f32_ptr_generic\n";
  4199. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4200. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4201. EXPECT_THAT(getDiagnosticString(),
  4202. HasSubstr("Operand '127[%_ptr_Generic_float]' cannot be a type"));
  4203. }
  4204. TEST_F(ValidateExtInst, VStoreNWrongStorageClass) {
  4205. std::ostringstream ss;
  4206. ss << "%ptr_w = OpAccessChain %f32_ptr_uniform_constant "
  4207. "%f32vec8_uniform_constant %u32_1\n";
  4208. ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_w\n";
  4209. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4210. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4211. EXPECT_THAT(
  4212. getDiagnosticString(),
  4213. HasSubstr("OpenCL.std vstoren: expected operand P storage class "
  4214. "to be Generic, CrossWorkgroup, Workgroup or Function"));
  4215. }
  4216. TEST_F(ValidateExtInst, VStorePWrongDataType) {
  4217. std::ostringstream ss;
  4218. ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
  4219. ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
  4220. ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
  4221. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4222. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4223. EXPECT_THAT(getDiagnosticString(),
  4224. HasSubstr("OpenCL.std vstoren: expected operand P data type to "
  4225. "be equal to the type of operand Data components"));
  4226. }
  4227. TEST_F(ValidateExtInst, OpenCLStdShuffleSuccess) {
  4228. const std::string body = R"(
  4229. %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %u32vec2_01
  4230. %val2 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec4_0123
  4231. %val3 = OpExtInst %u32vec2 %extinst shuffle %u32vec4_0123 %u32vec2_01
  4232. %val4 = OpExtInst %u32vec4 %extinst shuffle %u32vec4_0123 %u32vec4_0123
  4233. )";
  4234. CompileSuccessfully(GenerateKernelCode(body));
  4235. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4236. }
  4237. TEST_F(ValidateExtInst, OpenCLStdShuffleWrongResultType) {
  4238. const std::string body = R"(
  4239. %val1 = OpExtInst %f32 %extinst shuffle %f32vec4_0123 %u32vec2_01
  4240. )";
  4241. CompileSuccessfully(GenerateKernelCode(body));
  4242. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4243. EXPECT_THAT(
  4244. getDiagnosticString(),
  4245. HasSubstr("OpenCL.std shuffle: "
  4246. "expected Result Type to be an int or float vector type"));
  4247. }
  4248. TEST_F(ValidateExtInst, OpenCLStdShuffleResultTypeInvalidNumComponents) {
  4249. const std::string body = R"(
  4250. %val1 = OpExtInst %f32vec3 %extinst shuffle %f32vec4_0123 %u32vec3_012
  4251. )";
  4252. CompileSuccessfully(GenerateKernelCode(body));
  4253. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4254. EXPECT_THAT(
  4255. getDiagnosticString(),
  4256. HasSubstr("OpenCL.std shuffle: "
  4257. "expected Result Type to have 2, 4, 8 or 16 components"));
  4258. }
  4259. TEST_F(ValidateExtInst, OpenCLStdShuffleXWrongType) {
  4260. const std::string body = R"(
  4261. %val1 = OpExtInst %f32vec2 %extinst shuffle %f32_0 %u32vec2_01
  4262. )";
  4263. CompileSuccessfully(GenerateKernelCode(body));
  4264. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4265. EXPECT_THAT(getDiagnosticString(),
  4266. HasSubstr("OpenCL.std shuffle: "
  4267. "expected operand X to be an int or float vector"));
  4268. }
  4269. TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidNumComponents) {
  4270. const std::string body = R"(
  4271. %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec3_012 %u32vec2_01
  4272. )";
  4273. CompileSuccessfully(GenerateKernelCode(body));
  4274. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4275. EXPECT_THAT(getDiagnosticString(),
  4276. HasSubstr("OpenCL.std shuffle: "
  4277. "expected operand X to have 2, 4, 8 or 16 components"));
  4278. }
  4279. TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidComponentType) {
  4280. const std::string body = R"(
  4281. %val1 = OpExtInst %f32vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
  4282. )";
  4283. CompileSuccessfully(GenerateKernelCode(body));
  4284. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4285. EXPECT_THAT(
  4286. getDiagnosticString(),
  4287. HasSubstr(
  4288. "OpenCL.std shuffle: "
  4289. "expected operand X and Result Type to have equal component types"));
  4290. }
  4291. TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskNotIntVector) {
  4292. const std::string body = R"(
  4293. %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %f32vec2_01
  4294. )";
  4295. CompileSuccessfully(GenerateKernelCode(body));
  4296. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4297. EXPECT_THAT(getDiagnosticString(),
  4298. HasSubstr("OpenCL.std shuffle: "
  4299. "expected operand Shuffle Mask to be an int vector"));
  4300. }
  4301. TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidNumComponents) {
  4302. const std::string body = R"(
  4303. %val1 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec2_01
  4304. )";
  4305. CompileSuccessfully(GenerateKernelCode(body));
  4306. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4307. EXPECT_THAT(getDiagnosticString(),
  4308. HasSubstr("OpenCL.std shuffle: "
  4309. "expected operand Shuffle Mask to have the same number "
  4310. "of components as Result Type"));
  4311. }
  4312. TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidBitWidth) {
  4313. const std::string body = R"(
  4314. %val1 = OpExtInst %f64vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
  4315. )";
  4316. CompileSuccessfully(GenerateKernelCode(body));
  4317. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4318. EXPECT_THAT(getDiagnosticString(),
  4319. HasSubstr("OpenCL.std shuffle: "
  4320. "expected operand Shuffle Mask components to have the "
  4321. "same bit width as Result Type components"));
  4322. }
  4323. TEST_F(ValidateExtInst, OpenCLStdShuffle2Success) {
  4324. const std::string body = R"(
  4325. %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
  4326. %val2 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec4_0123
  4327. %val3 = OpExtInst %u32vec2 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec2_01
  4328. %val4 = OpExtInst %u32vec4 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
  4329. )";
  4330. CompileSuccessfully(GenerateKernelCode(body));
  4331. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4332. }
  4333. TEST_F(ValidateExtInst, OpenCLStdShuffle2WrongResultType) {
  4334. const std::string body = R"(
  4335. %val1 = OpExtInst %f32 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
  4336. )";
  4337. CompileSuccessfully(GenerateKernelCode(body));
  4338. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4339. EXPECT_THAT(
  4340. getDiagnosticString(),
  4341. HasSubstr("OpenCL.std shuffle2: "
  4342. "expected Result Type to be an int or float vector type"));
  4343. }
  4344. TEST_F(ValidateExtInst, OpenCLStdShuffle2ResultTypeInvalidNumComponents) {
  4345. const std::string body = R"(
  4346. %val1 = OpExtInst %f32vec3 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec3_012
  4347. )";
  4348. CompileSuccessfully(GenerateKernelCode(body));
  4349. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4350. EXPECT_THAT(
  4351. getDiagnosticString(),
  4352. HasSubstr("OpenCL.std shuffle2: "
  4353. "expected Result Type to have 2, 4, 8 or 16 components"));
  4354. }
  4355. TEST_F(ValidateExtInst, OpenCLStdShuffle2XWrongType) {
  4356. const std::string body = R"(
  4357. %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32_0 %f32_0 %u32vec2_01
  4358. )";
  4359. CompileSuccessfully(GenerateKernelCode(body));
  4360. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4361. EXPECT_THAT(getDiagnosticString(),
  4362. HasSubstr("OpenCL.std shuffle2: "
  4363. "expected operand X to be an int or float vector"));
  4364. }
  4365. TEST_F(ValidateExtInst, OpenCLStdShuffle2YTypeDifferentFromX) {
  4366. const std::string body = R"(
  4367. %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec2_01 %f32vec4_0123 %u32vec2_01
  4368. )";
  4369. CompileSuccessfully(GenerateKernelCode(body));
  4370. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4371. EXPECT_THAT(getDiagnosticString(),
  4372. HasSubstr("OpenCL.std shuffle2: "
  4373. "expected operands X and Y to be of the same type"));
  4374. }
  4375. TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidNumComponents) {
  4376. const std::string body = R"(
  4377. %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec3_012 %f32vec3_012 %u32vec2_01
  4378. )";
  4379. CompileSuccessfully(GenerateKernelCode(body));
  4380. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4381. EXPECT_THAT(getDiagnosticString(),
  4382. HasSubstr("OpenCL.std shuffle2: "
  4383. "expected operand X to have 2, 4, 8 or 16 components"));
  4384. }
  4385. TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidComponentType) {
  4386. const std::string body = R"(
  4387. %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
  4388. )";
  4389. CompileSuccessfully(GenerateKernelCode(body));
  4390. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4391. EXPECT_THAT(
  4392. getDiagnosticString(),
  4393. HasSubstr(
  4394. "OpenCL.std shuffle2: "
  4395. "expected operand X and Result Type to have equal component types"));
  4396. }
  4397. TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskNotIntVector) {
  4398. const std::string body = R"(
  4399. %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %f32vec2_01
  4400. )";
  4401. CompileSuccessfully(GenerateKernelCode(body));
  4402. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4403. EXPECT_THAT(getDiagnosticString(),
  4404. HasSubstr("OpenCL.std shuffle2: "
  4405. "expected operand Shuffle Mask to be an int vector"));
  4406. }
  4407. TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidNumComponents) {
  4408. const std::string body = R"(
  4409. %val1 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
  4410. )";
  4411. CompileSuccessfully(GenerateKernelCode(body));
  4412. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4413. EXPECT_THAT(getDiagnosticString(),
  4414. HasSubstr("OpenCL.std shuffle2: "
  4415. "expected operand Shuffle Mask to have the same number "
  4416. "of components as Result Type"));
  4417. }
  4418. TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidBitWidth) {
  4419. const std::string body = R"(
  4420. %val1 = OpExtInst %f64vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
  4421. )";
  4422. CompileSuccessfully(GenerateKernelCode(body));
  4423. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4424. EXPECT_THAT(getDiagnosticString(),
  4425. HasSubstr("OpenCL.std shuffle2: "
  4426. "expected operand Shuffle Mask components to have the "
  4427. "same bit width as Result Type components"));
  4428. }
  4429. TEST_F(ValidateExtInst, OpenCLStdPrintfSuccess) {
  4430. const std::string body = R"(
  4431. %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
  4432. %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
  4433. )";
  4434. CompileSuccessfully(GenerateKernelCode(body));
  4435. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4436. }
  4437. TEST_F(ValidateExtInst, OpenCLStdPrintfBoolResultType) {
  4438. const std::string body = R"(
  4439. %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
  4440. %val1 = OpExtInst %bool %extinst printf %format %u32_0 %u32_1
  4441. )";
  4442. CompileSuccessfully(GenerateKernelCode(body));
  4443. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4444. EXPECT_THAT(
  4445. getDiagnosticString(),
  4446. HasSubstr(
  4447. "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
  4448. }
  4449. TEST_F(ValidateExtInst, OpenCLStdPrintfU64ResultType) {
  4450. const std::string body = R"(
  4451. %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
  4452. %val1 = OpExtInst %u64 %extinst printf %format %u32_0 %u32_1
  4453. )";
  4454. CompileSuccessfully(GenerateKernelCode(body));
  4455. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4456. EXPECT_THAT(
  4457. getDiagnosticString(),
  4458. HasSubstr(
  4459. "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
  4460. }
  4461. TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotPointer) {
  4462. const std::string body = R"(
  4463. %val1 = OpExtInst %u32 %extinst printf %u8_ptr_uniform_constant %u32_0 %u32_1
  4464. )";
  4465. CompileSuccessfully(GenerateKernelCode(body));
  4466. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4467. EXPECT_THAT(
  4468. getDiagnosticString(),
  4469. HasSubstr("Operand '137[%_ptr_UniformConstant_uchar]' cannot be a "
  4470. "type"));
  4471. }
  4472. TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotUniformConstStorageClass) {
  4473. const std::string body = R"(
  4474. %format_const = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
  4475. %format = OpBitcast %u8_ptr_generic %format_const
  4476. %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
  4477. )";
  4478. CompileSuccessfully(GenerateKernelCode(body));
  4479. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4480. EXPECT_THAT(getDiagnosticString(),
  4481. HasSubstr("OpenCL.std printf: expected Format storage class to "
  4482. "be UniformConstant"));
  4483. }
  4484. TEST_F(ValidateExtInst,
  4485. OpenCLStdPrintfFormatWithExtensionNotAllowedStorageClass) {
  4486. const std::string body = R"(
  4487. %format_const = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
  4488. %format = OpBitcast %u8_ptr_input %format_const
  4489. %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
  4490. )";
  4491. const std::string extension = R"(
  4492. OpExtension "SPV_EXT_relaxed_printf_string_address_space"
  4493. )";
  4494. CompileSuccessfully(GenerateKernelCode(body, extension));
  4495. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4496. EXPECT_THAT(getDiagnosticString(),
  4497. HasSubstr("OpenCL.std printf: expected Format storage class to "
  4498. "be UniformConstant, Crossworkgroup, Workgroup, "
  4499. "Function, or Generic"));
  4500. }
  4501. TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotU8Pointer) {
  4502. const std::string body = R"(
  4503. %format = OpAccessChain %u32_ptr_uniform_constant %u32vec8_uniform_constant %u32_0
  4504. %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
  4505. )";
  4506. CompileSuccessfully(GenerateKernelCode(body));
  4507. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4508. EXPECT_THAT(
  4509. getDiagnosticString(),
  4510. HasSubstr(
  4511. "OpenCL.std printf: expected Format data type to be 8-bit int"));
  4512. }
  4513. TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Success) {
  4514. const std::string body = R"(
  4515. %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
  4516. %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
  4517. )";
  4518. CompileSuccessfully(GenerateKernelCode(body));
  4519. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4520. }
  4521. TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Physical64Success) {
  4522. const std::string body = R"(
  4523. %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
  4524. %val1 = OpExtInst %void %extinst prefetch %ptr %u64_256
  4525. )";
  4526. CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
  4527. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4528. }
  4529. TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Success) {
  4530. const std::string body = R"(
  4531. %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
  4532. %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
  4533. )";
  4534. CompileSuccessfully(GenerateKernelCode(body));
  4535. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4536. }
  4537. TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Vec2Success) {
  4538. const std::string body = R"(
  4539. %ptr = OpAccessChain %f32vec2_ptr_cross_workgroup %f32vec2arr_cross_workgroup %u32_0
  4540. %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
  4541. )";
  4542. CompileSuccessfully(GenerateKernelCode(body));
  4543. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4544. }
  4545. TEST_F(ValidateExtInst, OpenCLStdPrefetchResultTypeNotVoid) {
  4546. const std::string body = R"(
  4547. %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
  4548. %val1 = OpExtInst %u32 %extinst prefetch %ptr %u32_256
  4549. )";
  4550. CompileSuccessfully(GenerateKernelCode(body));
  4551. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4552. EXPECT_THAT(
  4553. getDiagnosticString(),
  4554. HasSubstr("OpenCL.std prefetch: expected Result Type to be void"));
  4555. }
  4556. TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotPointer) {
  4557. const std::string body = R"(
  4558. %val1 = OpExtInst %void %extinst prefetch %u32_ptr_cross_workgroup %u32_256
  4559. )";
  4560. CompileSuccessfully(GenerateKernelCode(body));
  4561. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  4562. EXPECT_THAT(getDiagnosticString(),
  4563. HasSubstr("Operand '99[%_ptr_CrossWorkgroup_uint]' cannot be a "
  4564. "type"));
  4565. }
  4566. TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotCrossWorkgroup) {
  4567. const std::string body = R"(
  4568. %ptr = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
  4569. %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
  4570. )";
  4571. CompileSuccessfully(GenerateKernelCode(body));
  4572. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4573. EXPECT_THAT(getDiagnosticString(),
  4574. HasSubstr("OpenCL.std prefetch: expected operand Ptr storage "
  4575. "class to be CrossWorkgroup"));
  4576. }
  4577. TEST_F(ValidateExtInst, OpenCLStdPrefetchInvalidDataType) {
  4578. const std::string body = R"(
  4579. %ptr = OpAccessChain %struct_ptr_cross_workgroup %struct_arr_cross_workgroup %u32_0
  4580. %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
  4581. )";
  4582. CompileSuccessfully(GenerateKernelCode(body));
  4583. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4584. EXPECT_THAT(getDiagnosticString(),
  4585. HasSubstr("OpenCL.std prefetch: expected Ptr data type to be int "
  4586. "or float scalar or vector"));
  4587. }
  4588. TEST_F(ValidateExtInst, OpenCLStdPrefetchAddressingModelLogical) {
  4589. const std::string body = R"(
  4590. %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
  4591. %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
  4592. )";
  4593. CompileSuccessfully(GenerateKernelCode(body, "", "Logical"));
  4594. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4595. EXPECT_THAT(getDiagnosticString(),
  4596. HasSubstr("OpenCL.std prefetch can only be used with physical "
  4597. "addressing models"));
  4598. }
  4599. TEST_F(ValidateExtInst, OpenCLStdPrefetchNumElementsNotSizeT) {
  4600. const std::string body = R"(
  4601. %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
  4602. %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
  4603. )";
  4604. CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
  4605. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4606. EXPECT_THAT(getDiagnosticString(),
  4607. HasSubstr("OpenCL.std prefetch: expected operand Num Elements to "
  4608. "be of type size_t (64-bit integer for the addressing "
  4609. "model used in the module)"));
  4610. }
  4611. TEST_P(ValidateOpenCLStdFractLike, Success) {
  4612. const std::string ext_inst_name = GetParam();
  4613. std::ostringstream ss;
  4614. ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
  4615. ss << "%var_f32vec2 = OpVariable %f32vec2_ptr_function Function\n";
  4616. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  4617. << " %f32_0 %var_f32\n";
  4618. ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  4619. << " %f32vec2_01 %var_f32vec2\n";
  4620. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4621. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4622. }
  4623. TEST_P(ValidateOpenCLStdFractLike, IntResultType) {
  4624. const std::string ext_inst_name = GetParam();
  4625. std::ostringstream ss;
  4626. ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
  4627. ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
  4628. << " %f32_0 %var_f32\n";
  4629. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4630. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4631. EXPECT_THAT(
  4632. getDiagnosticString(),
  4633. HasSubstr("OpenCL.std " + ext_inst_name +
  4634. ": expected Result Type to be a float scalar or vector type"));
  4635. }
  4636. TEST_P(ValidateOpenCLStdFractLike, XWrongType) {
  4637. const std::string ext_inst_name = GetParam();
  4638. std::ostringstream ss;
  4639. ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
  4640. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  4641. << " %f64_0 %var_f32\n";
  4642. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4643. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4644. EXPECT_THAT(
  4645. getDiagnosticString(),
  4646. HasSubstr("OpenCL.std " + ext_inst_name +
  4647. ": expected type of operand X to be equal to Result Type"));
  4648. }
  4649. TEST_P(ValidateOpenCLStdFractLike, NotPointer) {
  4650. const std::string ext_inst_name = GetParam();
  4651. std::ostringstream ss;
  4652. ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
  4653. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  4654. << " %f32_0 %f32_1\n";
  4655. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4656. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4657. EXPECT_THAT(getDiagnosticString(),
  4658. HasSubstr("OpenCL.std " + ext_inst_name +
  4659. ": expected the last operand to be a pointer"));
  4660. }
  4661. TEST_P(ValidateOpenCLStdFractLike, PointerInvalidStorageClass) {
  4662. const std::string ext_inst_name = GetParam();
  4663. std::ostringstream ss;
  4664. ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
  4665. "%f32vec8_uniform_constant %u32_1\n";
  4666. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
  4667. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4668. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4669. EXPECT_THAT(getDiagnosticString(),
  4670. HasSubstr("OpenCL.std " + ext_inst_name +
  4671. ": expected storage class of the pointer to be "
  4672. "Generic, CrossWorkgroup, Workgroup or Function"));
  4673. }
  4674. TEST_P(ValidateOpenCLStdFractLike, PointerWrongDataType) {
  4675. const std::string ext_inst_name = GetParam();
  4676. std::ostringstream ss;
  4677. ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
  4678. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  4679. << " %f32_0 %var_u32\n";
  4680. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4681. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4682. EXPECT_THAT(
  4683. getDiagnosticString(),
  4684. HasSubstr(
  4685. "OpenCL.std " + ext_inst_name +
  4686. ": expected data type of the pointer to be equal to Result Type"));
  4687. }
  4688. INSTANTIATE_TEST_SUITE_P(AllFractLike, ValidateOpenCLStdFractLike,
  4689. ::testing::ValuesIn(std::vector<std::string>{
  4690. "fract",
  4691. "modf",
  4692. "sincos",
  4693. }));
  4694. TEST_F(ValidateExtInst, OpenCLStdRemquoSuccess) {
  4695. const std::string body = R"(
  4696. %var_u32 = OpVariable %u32_ptr_function Function
  4697. %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
  4698. %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32
  4699. %val2 = OpExtInst %f32vec2 %extinst remquo %f32vec2_01 %f32vec2_12 %var_u32vec2
  4700. )";
  4701. CompileSuccessfully(GenerateKernelCode(body));
  4702. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4703. }
  4704. TEST_F(ValidateExtInst, OpenCLStdRemquoIntResultType) {
  4705. const std::string body = R"(
  4706. %var_u32 = OpVariable %u32_ptr_function Function
  4707. %val1 = OpExtInst %u32 %extinst remquo %f32_3 %f32_2 %var_u32
  4708. )";
  4709. CompileSuccessfully(GenerateKernelCode(body));
  4710. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4711. EXPECT_THAT(
  4712. getDiagnosticString(),
  4713. HasSubstr("OpenCL.std remquo: "
  4714. "expected Result Type to be a float scalar or vector type"));
  4715. }
  4716. TEST_F(ValidateExtInst, OpenCLStdRemquoXWrongType) {
  4717. const std::string body = R"(
  4718. %var_u32 = OpVariable %f32_ptr_function Function
  4719. %val1 = OpExtInst %f32 %extinst remquo %u32_3 %f32_2 %var_u32
  4720. )";
  4721. CompileSuccessfully(GenerateKernelCode(body));
  4722. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4723. EXPECT_THAT(
  4724. getDiagnosticString(),
  4725. HasSubstr("OpenCL.std remquo: "
  4726. "expected type of operand X to be equal to Result Type"));
  4727. }
  4728. TEST_F(ValidateExtInst, OpenCLStdRemquoYWrongType) {
  4729. const std::string body = R"(
  4730. %var_u32 = OpVariable %f32_ptr_function Function
  4731. %val1 = OpExtInst %f32 %extinst remquo %f32_3 %u32_2 %var_u32
  4732. )";
  4733. CompileSuccessfully(GenerateKernelCode(body));
  4734. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4735. EXPECT_THAT(
  4736. getDiagnosticString(),
  4737. HasSubstr("OpenCL.std remquo: "
  4738. "expected type of operand Y to be equal to Result Type"));
  4739. }
  4740. TEST_F(ValidateExtInst, OpenCLStdRemquoNotPointer) {
  4741. const std::string body = R"(
  4742. %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %f32_1
  4743. )";
  4744. CompileSuccessfully(GenerateKernelCode(body));
  4745. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4746. EXPECT_THAT(getDiagnosticString(),
  4747. HasSubstr("OpenCL.std remquo: "
  4748. "expected the last operand to be a pointer"));
  4749. }
  4750. TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongStorageClass) {
  4751. const std::string body = R"(
  4752. %ptr = OpAccessChain %f32_ptr_uniform_constant %f32vec8_uniform_constant %u32_1
  4753. %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %ptr
  4754. )";
  4755. CompileSuccessfully(GenerateKernelCode(body));
  4756. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4757. EXPECT_THAT(getDiagnosticString(),
  4758. HasSubstr("OpenCL.std remquo: "
  4759. "expected storage class of the pointer to be Generic, "
  4760. "CrossWorkgroup, Workgroup or Function"));
  4761. }
  4762. TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataType) {
  4763. const std::string body = R"(
  4764. %var_f32 = OpVariable %f32_ptr_function Function
  4765. %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_f32
  4766. )";
  4767. CompileSuccessfully(GenerateKernelCode(body));
  4768. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4769. EXPECT_THAT(getDiagnosticString(),
  4770. HasSubstr("OpenCL.std remquo: "
  4771. "expected data type of the pointer to be a 32-bit int "
  4772. "scalar or vector type"));
  4773. }
  4774. TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataTypeWidth) {
  4775. const std::string body = R"(
  4776. %var_u64 = OpVariable %u64_ptr_function Function
  4777. %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u64
  4778. )";
  4779. CompileSuccessfully(GenerateKernelCode(body));
  4780. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4781. EXPECT_THAT(getDiagnosticString(),
  4782. HasSubstr("OpenCL.std remquo: "
  4783. "expected data type of the pointer to be a 32-bit int "
  4784. "scalar or vector type"));
  4785. }
  4786. TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongNumberOfComponents) {
  4787. const std::string body = R"(
  4788. %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
  4789. %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32vec2
  4790. )";
  4791. CompileSuccessfully(GenerateKernelCode(body));
  4792. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4793. EXPECT_THAT(
  4794. getDiagnosticString(),
  4795. HasSubstr("OpenCL.std remquo: "
  4796. "expected data type of the pointer to have the same number "
  4797. "of components as Result Type"));
  4798. }
  4799. TEST_P(ValidateOpenCLStdFrexpLike, Success) {
  4800. const std::string ext_inst_name = GetParam();
  4801. std::ostringstream ss;
  4802. ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
  4803. ss << "%var_u32vec2 = OpVariable %u32vec2_ptr_function Function\n";
  4804. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  4805. << " %f32_0 %var_u32\n";
  4806. ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  4807. << " %f32vec2_01 %var_u32vec2\n";
  4808. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4809. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4810. }
  4811. TEST_P(ValidateOpenCLStdFrexpLike, IntResultType) {
  4812. const std::string ext_inst_name = GetParam();
  4813. std::ostringstream ss;
  4814. ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
  4815. ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
  4816. << " %f32_0 %var_u32\n";
  4817. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4818. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4819. EXPECT_THAT(
  4820. getDiagnosticString(),
  4821. HasSubstr("OpenCL.std " + ext_inst_name +
  4822. ": expected Result Type to be a float scalar or vector type"));
  4823. }
  4824. TEST_P(ValidateOpenCLStdFrexpLike, XWrongType) {
  4825. const std::string ext_inst_name = GetParam();
  4826. std::ostringstream ss;
  4827. ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
  4828. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  4829. << " %f64_0 %var_u32\n";
  4830. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4831. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4832. EXPECT_THAT(
  4833. getDiagnosticString(),
  4834. HasSubstr("OpenCL.std " + ext_inst_name +
  4835. ": expected type of operand X to be equal to Result Type"));
  4836. }
  4837. TEST_P(ValidateOpenCLStdFrexpLike, NotPointer) {
  4838. const std::string ext_inst_name = GetParam();
  4839. std::ostringstream ss;
  4840. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  4841. << " %f32_0 %u32_1\n";
  4842. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4843. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4844. EXPECT_THAT(getDiagnosticString(),
  4845. HasSubstr("OpenCL.std " + ext_inst_name +
  4846. ": expected the last operand to be a pointer"));
  4847. }
  4848. TEST_P(ValidateOpenCLStdFrexpLike, PointerInvalidStorageClass) {
  4849. const std::string ext_inst_name = GetParam();
  4850. std::ostringstream ss;
  4851. ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
  4852. "%f32vec8_uniform_constant %u32_1\n";
  4853. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
  4854. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4855. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4856. EXPECT_THAT(getDiagnosticString(),
  4857. HasSubstr("OpenCL.std " + ext_inst_name +
  4858. ": expected storage class of the pointer to be "
  4859. "Generic, CrossWorkgroup, Workgroup or Function"));
  4860. }
  4861. TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeFloat) {
  4862. const std::string ext_inst_name = GetParam();
  4863. std::ostringstream ss;
  4864. ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
  4865. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  4866. << " %f32_0 %var_f32\n";
  4867. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4868. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4869. EXPECT_THAT(getDiagnosticString(),
  4870. HasSubstr("OpenCL.std " + ext_inst_name +
  4871. ": expected data type of the pointer to be a 32-bit "
  4872. "int scalar or vector type"));
  4873. }
  4874. TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeU64) {
  4875. const std::string ext_inst_name = GetParam();
  4876. std::ostringstream ss;
  4877. ss << "%var_u64 = OpVariable %u64_ptr_function Function\n";
  4878. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  4879. << " %f32_0 %var_u64\n";
  4880. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4881. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4882. EXPECT_THAT(getDiagnosticString(),
  4883. HasSubstr("OpenCL.std " + ext_inst_name +
  4884. ": expected data type of the pointer to be a 32-bit "
  4885. "int scalar or vector type"));
  4886. }
  4887. TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeDiffSize) {
  4888. const std::string ext_inst_name = GetParam();
  4889. std::ostringstream ss;
  4890. ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
  4891. ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  4892. << " %f32vec2_01 %var_u32\n";
  4893. CompileSuccessfully(GenerateKernelCode(ss.str()));
  4894. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4895. EXPECT_THAT(getDiagnosticString(),
  4896. HasSubstr("OpenCL.std " + ext_inst_name +
  4897. ": expected data type of the pointer to have the same "
  4898. "number of components as Result Type"));
  4899. }
  4900. INSTANTIATE_TEST_SUITE_P(AllFrexpLike, ValidateOpenCLStdFrexpLike,
  4901. ::testing::ValuesIn(std::vector<std::string>{
  4902. "frexp",
  4903. "lgamma_r",
  4904. }));
  4905. TEST_F(ValidateExtInst, OpenCLStdIlogbSuccess) {
  4906. const std::string body = R"(
  4907. %val1 = OpExtInst %u32 %extinst ilogb %f32_3
  4908. %val2 = OpExtInst %u32vec2 %extinst ilogb %f32vec2_12
  4909. )";
  4910. CompileSuccessfully(GenerateKernelCode(body));
  4911. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4912. }
  4913. TEST_F(ValidateExtInst, OpenCLStdIlogbFloatResultType) {
  4914. const std::string body = R"(
  4915. %val1 = OpExtInst %f32 %extinst ilogb %f32_3
  4916. )";
  4917. CompileSuccessfully(GenerateKernelCode(body));
  4918. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4919. EXPECT_THAT(
  4920. getDiagnosticString(),
  4921. HasSubstr(
  4922. "OpenCL.std ilogb: "
  4923. "expected Result Type to be a 32-bit int scalar or vector type"));
  4924. }
  4925. TEST_F(ValidateExtInst, OpenCLStdIlogbIntX) {
  4926. const std::string body = R"(
  4927. %val1 = OpExtInst %u32 %extinst ilogb %u32_3
  4928. )";
  4929. CompileSuccessfully(GenerateKernelCode(body));
  4930. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4931. EXPECT_THAT(getDiagnosticString(),
  4932. HasSubstr("OpenCL.std ilogb: "
  4933. "expected operand X to be a float scalar or vector"));
  4934. }
  4935. TEST_F(ValidateExtInst, OpenCLStdIlogbDiffSize) {
  4936. const std::string body = R"(
  4937. %val2 = OpExtInst %u32vec2 %extinst ilogb %f32_1
  4938. )";
  4939. CompileSuccessfully(GenerateKernelCode(body));
  4940. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4941. EXPECT_THAT(getDiagnosticString(),
  4942. HasSubstr("OpenCL.std ilogb: "
  4943. "expected operand X to have the same number of "
  4944. "components as Result Type"));
  4945. }
  4946. TEST_F(ValidateExtInst, OpenCLStdNanSuccess) {
  4947. const std::string body = R"(
  4948. %val1 = OpExtInst %f32 %extinst nan %u32_3
  4949. %val2 = OpExtInst %f32vec2 %extinst nan %u32vec2_12
  4950. )";
  4951. CompileSuccessfully(GenerateKernelCode(body));
  4952. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  4953. }
  4954. TEST_F(ValidateExtInst, OpenCLStdNanIntResultType) {
  4955. const std::string body = R"(
  4956. %val1 = OpExtInst %u32 %extinst nan %u32_3
  4957. )";
  4958. CompileSuccessfully(GenerateKernelCode(body));
  4959. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4960. EXPECT_THAT(
  4961. getDiagnosticString(),
  4962. HasSubstr("OpenCL.std nan: "
  4963. "expected Result Type to be a float scalar or vector type"));
  4964. }
  4965. TEST_F(ValidateExtInst, OpenCLStdNanFloatNancode) {
  4966. const std::string body = R"(
  4967. %val1 = OpExtInst %f32 %extinst nan %f32_3
  4968. )";
  4969. CompileSuccessfully(GenerateKernelCode(body));
  4970. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4971. EXPECT_THAT(getDiagnosticString(),
  4972. HasSubstr("OpenCL.std nan: "
  4973. "expected Nancode to be an int scalar or vector type"));
  4974. }
  4975. TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffSize) {
  4976. const std::string body = R"(
  4977. %val1 = OpExtInst %f32 %extinst nan %u32vec2_12
  4978. )";
  4979. CompileSuccessfully(GenerateKernelCode(body));
  4980. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4981. EXPECT_THAT(getDiagnosticString(),
  4982. HasSubstr("OpenCL.std nan: "
  4983. "expected Nancode to have the same number of "
  4984. "components as Result Type"));
  4985. }
  4986. TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffBitWidth) {
  4987. const std::string body = R"(
  4988. %val1 = OpExtInst %f64 %extinst nan %u32_2
  4989. )";
  4990. CompileSuccessfully(GenerateKernelCode(body));
  4991. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  4992. EXPECT_THAT(
  4993. getDiagnosticString(),
  4994. HasSubstr("OpenCL.std nan: "
  4995. "expected Nancode to have the same bit width as Result Type"));
  4996. }
  4997. TEST_P(ValidateOpenCLStdLdexpLike, Success) {
  4998. const std::string ext_inst_name = GetParam();
  4999. std::ostringstream ss;
  5000. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  5001. << " %f32_0 %u32_1\n";
  5002. ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
  5003. << " %f32vec2_12 %u32vec2_12\n";
  5004. CompileSuccessfully(GenerateKernelCode(ss.str()));
  5005. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5006. }
  5007. TEST_P(ValidateOpenCLStdLdexpLike, IntResultType) {
  5008. const std::string ext_inst_name = GetParam();
  5009. std::ostringstream ss;
  5010. ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
  5011. << " %f32_0 %u32_1\n";
  5012. CompileSuccessfully(GenerateKernelCode(ss.str()));
  5013. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5014. EXPECT_THAT(
  5015. getDiagnosticString(),
  5016. HasSubstr("OpenCL.std " + ext_inst_name +
  5017. ": expected Result Type to be a float scalar or vector type"));
  5018. }
  5019. TEST_P(ValidateOpenCLStdLdexpLike, XWrongType) {
  5020. const std::string ext_inst_name = GetParam();
  5021. std::ostringstream ss;
  5022. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  5023. << " %u32_0 %u32_1\n";
  5024. CompileSuccessfully(GenerateKernelCode(ss.str()));
  5025. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5026. EXPECT_THAT(
  5027. getDiagnosticString(),
  5028. HasSubstr("OpenCL.std " + ext_inst_name +
  5029. ": expected type of operand X to be equal to Result Type"));
  5030. }
  5031. TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt) {
  5032. const std::string ext_inst_name = GetParam();
  5033. std::ostringstream ss;
  5034. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  5035. << " %f32_0 %f32_1\n";
  5036. CompileSuccessfully(GenerateKernelCode(ss.str()));
  5037. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5038. EXPECT_THAT(
  5039. getDiagnosticString(),
  5040. HasSubstr("OpenCL.std " + ext_inst_name +
  5041. ": expected the exponent to be a 32-bit int scalar or vector"));
  5042. }
  5043. TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt32) {
  5044. const std::string ext_inst_name = GetParam();
  5045. std::ostringstream ss;
  5046. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  5047. << " %f32_0 %u64_1\n";
  5048. CompileSuccessfully(GenerateKernelCode(ss.str()));
  5049. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5050. EXPECT_THAT(
  5051. getDiagnosticString(),
  5052. HasSubstr("OpenCL.std " + ext_inst_name +
  5053. ": expected the exponent to be a 32-bit int scalar or vector"));
  5054. }
  5055. TEST_P(ValidateOpenCLStdLdexpLike, ExponentWrongSize) {
  5056. const std::string ext_inst_name = GetParam();
  5057. std::ostringstream ss;
  5058. ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
  5059. << " %f32_0 %u32vec2_01\n";
  5060. CompileSuccessfully(GenerateKernelCode(ss.str()));
  5061. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5062. EXPECT_THAT(getDiagnosticString(),
  5063. HasSubstr("OpenCL.std " + ext_inst_name +
  5064. ": expected the exponent to have the same number of "
  5065. "components as Result Type"));
  5066. }
  5067. INSTANTIATE_TEST_SUITE_P(AllLdexpLike, ValidateOpenCLStdLdexpLike,
  5068. ::testing::ValuesIn(std::vector<std::string>{
  5069. "ldexp",
  5070. "pown",
  5071. "rootn",
  5072. }));
  5073. TEST_P(ValidateOpenCLStdUpsampleLike, Success) {
  5074. const std::string ext_inst_name = GetParam();
  5075. std::ostringstream ss;
  5076. ss << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
  5077. ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
  5078. << " %u16_1 %u16_2\n";
  5079. ss << "%val3 = OpExtInst %u64 %extinst " << ext_inst_name
  5080. << " %u32_1 %u32_2\n";
  5081. ss << "%val4 = OpExtInst %u64vec2 %extinst " << ext_inst_name
  5082. << " %u32vec2_01 %u32vec2_01\n";
  5083. CompileSuccessfully(GenerateKernelCode(ss.str()));
  5084. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5085. }
  5086. TEST_P(ValidateOpenCLStdUpsampleLike, FloatResultType) {
  5087. const std::string ext_inst_name = GetParam();
  5088. std::ostringstream ss;
  5089. ss << "%val1 = OpExtInst %f64 %extinst " << ext_inst_name
  5090. << " %u32_1 %u32_2\n";
  5091. CompileSuccessfully(GenerateKernelCode(ss.str()));
  5092. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5093. EXPECT_THAT(
  5094. getDiagnosticString(),
  5095. HasSubstr("OpenCL.std " + ext_inst_name +
  5096. ": expected Result Type to be an int scalar or vector type"));
  5097. }
  5098. TEST_P(ValidateOpenCLStdUpsampleLike, InvalidResultTypeBitWidth) {
  5099. const std::string ext_inst_name = GetParam();
  5100. std::ostringstream ss;
  5101. ss << "%val1 = OpExtInst %u8 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
  5102. CompileSuccessfully(GenerateKernelCode(ss.str()));
  5103. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5104. EXPECT_THAT(
  5105. getDiagnosticString(),
  5106. HasSubstr(
  5107. "OpenCL.std " + ext_inst_name +
  5108. ": expected bit width of Result Type components to be 16, 32 or 64"));
  5109. }
  5110. TEST_P(ValidateOpenCLStdUpsampleLike, LoHiDiffType) {
  5111. const std::string ext_inst_name = GetParam();
  5112. std::ostringstream ss;
  5113. ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
  5114. << " %u32_1 %u16_2\n";
  5115. CompileSuccessfully(GenerateKernelCode(ss.str()));
  5116. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5117. EXPECT_THAT(getDiagnosticString(),
  5118. HasSubstr("OpenCL.std " + ext_inst_name +
  5119. ": expected Hi and Lo operands to have the same type"));
  5120. }
  5121. TEST_P(ValidateOpenCLStdUpsampleLike, DiffNumberOfComponents) {
  5122. const std::string ext_inst_name = GetParam();
  5123. std::ostringstream ss;
  5124. ss << "%val1 = OpExtInst %u64vec2 %extinst " << ext_inst_name
  5125. << " %u32_1 %u32_2\n";
  5126. CompileSuccessfully(GenerateKernelCode(ss.str()));
  5127. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5128. EXPECT_THAT(getDiagnosticString(),
  5129. HasSubstr("OpenCL.std " + ext_inst_name +
  5130. ": expected Hi and Lo operands to have the same number "
  5131. "of components as Result Type"));
  5132. }
  5133. TEST_P(ValidateOpenCLStdUpsampleLike, HiLoWrongBitWidth) {
  5134. const std::string ext_inst_name = GetParam();
  5135. std::ostringstream ss;
  5136. ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
  5137. << " %u16_1 %u16_2\n";
  5138. CompileSuccessfully(GenerateKernelCode(ss.str()));
  5139. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5140. EXPECT_THAT(
  5141. getDiagnosticString(),
  5142. HasSubstr("OpenCL.std " + ext_inst_name +
  5143. ": expected bit width of components of Hi and Lo operands to "
  5144. "be half of the bit width of components of Result Type"));
  5145. }
  5146. INSTANTIATE_TEST_SUITE_P(AllUpsampleLike, ValidateOpenCLStdUpsampleLike,
  5147. ::testing::ValuesIn(std::vector<std::string>{
  5148. "u_upsample",
  5149. "s_upsample",
  5150. }));
  5151. TEST_F(ValidateClspvReflection, RequiresNonSemanticExtension) {
  5152. const std::string text = R"(
  5153. OpCapability Shader
  5154. OpCapability Linkage
  5155. %1 = OpExtInstImport "NonSemantic.ClspvReflection.1"
  5156. OpMemoryModel Logical GLSL450
  5157. )";
  5158. CompileSuccessfully(text);
  5159. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5160. EXPECT_THAT(getDiagnosticString(),
  5161. HasSubstr("NonSemantic extended instruction sets cannot be "
  5162. "declared without SPV_KHR_non_semantic_info"));
  5163. }
  5164. TEST_F(ValidateClspvReflection, DoesNotRequiresNonSemanticExtensionPost1p6) {
  5165. const std::string text = R"(
  5166. OpCapability Shader
  5167. OpCapability Linkage
  5168. %1 = OpExtInstImport "NonSemantic.ClspvReflection.1"
  5169. OpMemoryModel Logical GLSL450
  5170. )";
  5171. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_6);
  5172. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
  5173. }
  5174. TEST_F(ValidateClspvReflection, MissingVersion) {
  5175. const std::string text = R"(
  5176. OpCapability Shader
  5177. OpCapability Linkage
  5178. OpExtension "SPV_KHR_non_semantic_info"
  5179. %1 = OpExtInstImport "NonSemantic.ClspvReflection."
  5180. OpMemoryModel Logical GLSL450
  5181. %2 = OpTypeVoid
  5182. %3 = OpTypeInt 32 0
  5183. %4 = OpConstant %3 1
  5184. %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
  5185. )";
  5186. CompileSuccessfully(text);
  5187. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5188. EXPECT_THAT(getDiagnosticString(),
  5189. HasSubstr("Missing NonSemantic.ClspvReflection import version"));
  5190. }
  5191. TEST_F(ValidateClspvReflection, BadVersion0) {
  5192. const std::string text = R"(
  5193. OpCapability Shader
  5194. OpCapability Linkage
  5195. OpExtension "SPV_KHR_non_semantic_info"
  5196. %1 = OpExtInstImport "NonSemantic.ClspvReflection.0"
  5197. OpMemoryModel Logical GLSL450
  5198. %2 = OpTypeVoid
  5199. %3 = OpTypeInt 32 0
  5200. %4 = OpConstant %3 1
  5201. %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
  5202. )";
  5203. CompileSuccessfully(text);
  5204. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5205. EXPECT_THAT(getDiagnosticString(),
  5206. HasSubstr("Unknown NonSemantic.ClspvReflection import version"));
  5207. }
  5208. TEST_F(ValidateClspvReflection, BadVersionNotANumber) {
  5209. const std::string text = R"(
  5210. OpCapability Shader
  5211. OpCapability Linkage
  5212. OpExtension "SPV_KHR_non_semantic_info"
  5213. %1 = OpExtInstImport "NonSemantic.ClspvReflection.1a"
  5214. OpMemoryModel Logical GLSL450
  5215. %2 = OpTypeVoid
  5216. %3 = OpTypeInt 32 0
  5217. %4 = OpConstant %3 1
  5218. %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
  5219. )";
  5220. CompileSuccessfully(text);
  5221. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  5222. EXPECT_THAT(getDiagnosticString(),
  5223. HasSubstr("NonSemantic.ClspvReflection import does not encode "
  5224. "the version correctly"));
  5225. }
  5226. TEST_F(ValidateClspvReflection, Kernel) {
  5227. const std::string text = R"(
  5228. OpCapability Shader
  5229. OpExtension "SPV_KHR_non_semantic_info"
  5230. %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
  5231. OpMemoryModel Logical GLSL450
  5232. OpEntryPoint GLCompute %foo "foo"
  5233. OpExecutionMode %foo LocalSize 1 1 1
  5234. %foo_name = OpString "foo"
  5235. %void = OpTypeVoid
  5236. %void_fn = OpTypeFunction %void
  5237. %foo = OpFunction %void None %void_fn
  5238. %entry = OpLabel
  5239. OpReturn
  5240. OpFunctionEnd
  5241. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  5242. )";
  5243. CompileSuccessfully(text);
  5244. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5245. }
  5246. TEST_F(ValidateClspvReflection, KernelNotAFunction) {
  5247. const std::string text = R"(
  5248. OpCapability Shader
  5249. OpExtension "SPV_KHR_non_semantic_info"
  5250. %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
  5251. OpMemoryModel Logical GLSL450
  5252. OpEntryPoint GLCompute %foo "foo"
  5253. OpExecutionMode %foo LocalSize 1 1 1
  5254. %foo_name = OpString "foo"
  5255. %void = OpTypeVoid
  5256. %void_fn = OpTypeFunction %void
  5257. %foo = OpFunction %void None %void_fn
  5258. %entry = OpLabel
  5259. OpReturn
  5260. OpFunctionEnd
  5261. %decl = OpExtInst %void %ext Kernel %foo_name %foo_name
  5262. )";
  5263. CompileSuccessfully(text);
  5264. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5265. EXPECT_THAT(getDiagnosticString(),
  5266. HasSubstr("Kernel does not reference a function"));
  5267. }
  5268. TEST_F(ValidateClspvReflection, KernelNotAnEntryPoint) {
  5269. const std::string text = R"(
  5270. OpCapability Shader
  5271. OpExtension "SPV_KHR_non_semantic_info"
  5272. %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
  5273. OpMemoryModel Logical GLSL450
  5274. OpEntryPoint GLCompute %foo "foo"
  5275. OpExecutionMode %foo LocalSize 1 1 1
  5276. %foo_name = OpString "foo"
  5277. %void = OpTypeVoid
  5278. %void_fn = OpTypeFunction %void
  5279. %foo = OpFunction %void None %void_fn
  5280. %entry = OpLabel
  5281. OpReturn
  5282. OpFunctionEnd
  5283. %bar = OpFunction %void None %void_fn
  5284. %bar_entry = OpLabel
  5285. OpReturn
  5286. OpFunctionEnd
  5287. %decl = OpExtInst %void %ext Kernel %bar %foo_name
  5288. )";
  5289. CompileSuccessfully(text);
  5290. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5291. EXPECT_THAT(getDiagnosticString(),
  5292. HasSubstr("Kernel does not reference an entry-point"));
  5293. }
  5294. TEST_F(ValidateClspvReflection, KernelNotGLCompute) {
  5295. const std::string text = R"(
  5296. OpCapability Shader
  5297. OpExtension "SPV_KHR_non_semantic_info"
  5298. %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
  5299. OpMemoryModel Logical GLSL450
  5300. OpEntryPoint Fragment %foo "foo"
  5301. OpExecutionMode %foo OriginUpperLeft
  5302. %foo_name = OpString "foo"
  5303. %void = OpTypeVoid
  5304. %void_fn = OpTypeFunction %void
  5305. %foo = OpFunction %void None %void_fn
  5306. %entry = OpLabel
  5307. OpReturn
  5308. OpFunctionEnd
  5309. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  5310. )";
  5311. CompileSuccessfully(text);
  5312. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5313. EXPECT_THAT(getDiagnosticString(),
  5314. HasSubstr("Kernel must refer only to GLCompute entry-points"));
  5315. }
  5316. TEST_F(ValidateClspvReflection, KernelNameMismatch) {
  5317. const std::string text = R"(
  5318. OpCapability Shader
  5319. OpExtension "SPV_KHR_non_semantic_info"
  5320. %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
  5321. OpMemoryModel Logical GLSL450
  5322. OpEntryPoint GLCompute %foo "foo"
  5323. OpExecutionMode %foo LocalSize 1 1 1
  5324. %foo_name = OpString "bar"
  5325. %void = OpTypeVoid
  5326. %void_fn = OpTypeFunction %void
  5327. %foo = OpFunction %void None %void_fn
  5328. %entry = OpLabel
  5329. OpReturn
  5330. OpFunctionEnd
  5331. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  5332. )";
  5333. CompileSuccessfully(text);
  5334. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5335. EXPECT_THAT(getDiagnosticString(),
  5336. HasSubstr("Name must match an entry-point for Kernel"));
  5337. }
  5338. TEST_F(ValidateClspvReflection, KernelArgumentsVersionGood) {
  5339. const std::string text = R"(
  5340. OpCapability Shader
  5341. OpExtension "SPV_KHR_non_semantic_info"
  5342. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5343. OpMemoryModel Logical GLSL450
  5344. OpEntryPoint GLCompute %foo "foo"
  5345. OpExecutionMode %foo LocalSize 1 1 1
  5346. %foo_name = OpString "foo"
  5347. %void = OpTypeVoid
  5348. %void_fn = OpTypeFunction %void
  5349. %int = OpTypeInt 32 0
  5350. %int_1 = OpConstant %int 1
  5351. %foo = OpFunction %void None %void_fn
  5352. %entry = OpLabel
  5353. OpReturn
  5354. OpFunctionEnd
  5355. %decl = OpExtInst %void %ext Kernel %foo %foo_name %int_1
  5356. )";
  5357. CompileSuccessfully(text);
  5358. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5359. }
  5360. TEST_F(ValidateClspvReflection, KernelArgumentsVersionBad) {
  5361. const std::string text = R"(
  5362. OpCapability Shader
  5363. OpExtension "SPV_KHR_non_semantic_info"
  5364. %ext = OpExtInstImport "NonSemantic.ClspvReflection.4"
  5365. OpMemoryModel Logical GLSL450
  5366. OpEntryPoint GLCompute %foo "foo"
  5367. OpExecutionMode %foo LocalSize 1 1 1
  5368. %foo_name = OpString "foo"
  5369. %void = OpTypeVoid
  5370. %void_fn = OpTypeFunction %void
  5371. %int = OpTypeInt 32 0
  5372. %int_1 = OpConstant %int 1
  5373. %foo = OpFunction %void None %void_fn
  5374. %entry = OpLabel
  5375. OpReturn
  5376. OpFunctionEnd
  5377. %decl = OpExtInst %void %ext Kernel %foo %foo_name %int_1
  5378. )";
  5379. CompileSuccessfully(text);
  5380. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5381. EXPECT_THAT(getDiagnosticString(),
  5382. HasSubstr("Version 4 of the Kernel instruction can only have 2 "
  5383. "additional operands"));
  5384. }
  5385. TEST_F(ValidateClspvReflection, KernelNumArgumentsNotInt) {
  5386. const std::string text = R"(
  5387. OpCapability Shader
  5388. OpExtension "SPV_KHR_non_semantic_info"
  5389. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5390. OpMemoryModel Logical GLSL450
  5391. OpEntryPoint GLCompute %foo "foo"
  5392. OpExecutionMode %foo LocalSize 1 1 1
  5393. %foo_name = OpString "foo"
  5394. %void = OpTypeVoid
  5395. %void_fn = OpTypeFunction %void
  5396. %int = OpTypeInt 32 0
  5397. %int_0 = OpConstant %int 0
  5398. %float = OpTypeFloat 32
  5399. %float_0 = OpConstant %float 0
  5400. %foo = OpFunction %void None %void_fn
  5401. %entry = OpLabel
  5402. OpReturn
  5403. OpFunctionEnd
  5404. %decl = OpExtInst %void %ext Kernel %foo %foo_name %float_0
  5405. )";
  5406. CompileSuccessfully(text);
  5407. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5408. EXPECT_THAT(
  5409. getDiagnosticString(),
  5410. HasSubstr("NumArguments must be a 32-bit unsigned integer OpConstant"));
  5411. }
  5412. TEST_F(ValidateClspvReflection, KernelNumArgumentsNotConstant) {
  5413. const std::string text = R"(
  5414. OpCapability Shader
  5415. OpExtension "SPV_KHR_non_semantic_info"
  5416. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5417. OpMemoryModel Logical GLSL450
  5418. OpEntryPoint GLCompute %foo "foo"
  5419. OpExecutionMode %foo LocalSize 1 1 1
  5420. %foo_name = OpString "foo"
  5421. %void = OpTypeVoid
  5422. %void_fn = OpTypeFunction %void
  5423. %int = OpTypeInt 32 0
  5424. %int_0 = OpConstant %int 0
  5425. %null = OpConstantNull %int
  5426. %foo = OpFunction %void None %void_fn
  5427. %entry = OpLabel
  5428. OpReturn
  5429. OpFunctionEnd
  5430. %decl = OpExtInst %void %ext Kernel %foo %foo_name %null
  5431. )";
  5432. CompileSuccessfully(text);
  5433. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5434. EXPECT_THAT(
  5435. getDiagnosticString(),
  5436. HasSubstr("NumArguments must be a 32-bit unsigned integer OpConstant"));
  5437. }
  5438. TEST_F(ValidateClspvReflection, KernelFlagsNotInt) {
  5439. const std::string text = R"(
  5440. OpCapability Shader
  5441. OpExtension "SPV_KHR_non_semantic_info"
  5442. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5443. OpMemoryModel Logical GLSL450
  5444. OpEntryPoint GLCompute %foo "foo"
  5445. OpExecutionMode %foo LocalSize 1 1 1
  5446. %foo_name = OpString "foo"
  5447. %void = OpTypeVoid
  5448. %void_fn = OpTypeFunction %void
  5449. %int = OpTypeInt 32 0
  5450. %int_0 = OpConstant %int 0
  5451. %float = OpTypeFloat 32
  5452. %float_0 = OpConstant %float 0
  5453. %foo = OpFunction %void None %void_fn
  5454. %entry = OpLabel
  5455. OpReturn
  5456. OpFunctionEnd
  5457. %decl = OpExtInst %void %ext Kernel %foo %foo_name %int_0 %float_0
  5458. )";
  5459. CompileSuccessfully(text);
  5460. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5461. EXPECT_THAT(getDiagnosticString(),
  5462. HasSubstr("Flags must be a 32-bit unsigned integer OpConstant"));
  5463. }
  5464. TEST_F(ValidateClspvReflection, KernelFlagsNotConstant) {
  5465. const std::string text = R"(
  5466. OpCapability Shader
  5467. OpExtension "SPV_KHR_non_semantic_info"
  5468. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5469. OpMemoryModel Logical GLSL450
  5470. OpEntryPoint GLCompute %foo "foo"
  5471. OpExecutionMode %foo LocalSize 1 1 1
  5472. %foo_name = OpString "foo"
  5473. %void = OpTypeVoid
  5474. %void_fn = OpTypeFunction %void
  5475. %int = OpTypeInt 32 0
  5476. %int_0 = OpConstant %int 0
  5477. %null = OpConstantNull %int
  5478. %foo = OpFunction %void None %void_fn
  5479. %entry = OpLabel
  5480. OpReturn
  5481. OpFunctionEnd
  5482. %decl = OpExtInst %void %ext Kernel %foo %foo_name %int_0 %null
  5483. )";
  5484. CompileSuccessfully(text);
  5485. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5486. EXPECT_THAT(getDiagnosticString(),
  5487. HasSubstr("Flags must be a 32-bit unsigned integer OpConstant"));
  5488. }
  5489. TEST_F(ValidateClspvReflection, KernelAttributesNotString) {
  5490. const std::string text = R"(
  5491. OpCapability Shader
  5492. OpExtension "SPV_KHR_non_semantic_info"
  5493. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5494. OpMemoryModel Logical GLSL450
  5495. OpEntryPoint GLCompute %foo "foo"
  5496. OpExecutionMode %foo LocalSize 1 1 1
  5497. %foo_name = OpString "foo"
  5498. %void = OpTypeVoid
  5499. %void_fn = OpTypeFunction %void
  5500. %int = OpTypeInt 32 0
  5501. %int_0 = OpConstant %int 0
  5502. %float = OpTypeFloat 32
  5503. %float_0 = OpConstant %float 0
  5504. %foo = OpFunction %void None %void_fn
  5505. %entry = OpLabel
  5506. OpReturn
  5507. OpFunctionEnd
  5508. %decl = OpExtInst %void %ext Kernel %foo %foo_name %int_0 %int_0 %int_0
  5509. )";
  5510. CompileSuccessfully(text);
  5511. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5512. EXPECT_THAT(getDiagnosticString(),
  5513. HasSubstr("Attributes must be an OpString"));
  5514. }
  5515. using ArgumentBasics =
  5516. spvtest::ValidateBase<std::pair<std::string, std::string>>;
  5517. INSTANTIATE_TEST_SUITE_P(
  5518. ValidateClspvReflectionArgumentKernel, ArgumentBasics,
  5519. ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
  5520. std::make_pair("ArgumentStorageBuffer", "%int_0 %int_0"),
  5521. std::make_pair("ArgumentUniform", "%int_0 %int_0"),
  5522. std::make_pair("ArgumentPodStorageBuffer",
  5523. "%int_0 %int_0 %int_0 %int_4"),
  5524. std::make_pair("ArgumentPodUniform", "%int_0 %int_0 %int_0 %int_4"),
  5525. std::make_pair("ArgumentPodPushConstant", "%int_0 %int_4"),
  5526. std::make_pair("ArgumentSampledImage", "%int_0 %int_0"),
  5527. std::make_pair("ArgumentStorageImage", "%int_0 %int_0"),
  5528. std::make_pair("ArgumentSampler", "%int_0 %int_0"),
  5529. std::make_pair("ArgumentWorkgroup", "%int_0 %int_0"),
  5530. std::make_pair("ArgumentPointerPushConstant", "%int_0 %int_4"),
  5531. std::make_pair("ArgumentPointerUniform", "%int_0 %int_0 %int_0 %int_4"),
  5532. std::make_pair("ArgumentStorageTexelBuffer", "%int_0 %int_0"),
  5533. std::make_pair("ArgumentUniformTexelBuffer", "%int_0 %int_0")}));
  5534. TEST_P(ArgumentBasics, KernelNotAnExtendedInstruction) {
  5535. const std::string ext_inst = std::get<0>(GetParam());
  5536. const std::string extra = std::get<1>(GetParam());
  5537. const std::string text = R"(
  5538. OpCapability Shader
  5539. OpExtension "SPV_KHR_non_semantic_info"
  5540. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5541. OpMemoryModel Logical GLSL450
  5542. OpEntryPoint GLCompute %foo "foo"
  5543. OpExecutionMode %foo LocalSize 1 1 1
  5544. %foo_name = OpString "foo"
  5545. %void = OpTypeVoid
  5546. %int = OpTypeInt 32 0
  5547. %int_0 = OpConstant %int 0
  5548. %int_4 = OpConstant %int 4
  5549. %void_fn = OpTypeFunction %void
  5550. %foo = OpFunction %void None %void_fn
  5551. %entry = OpLabel
  5552. OpReturn
  5553. OpFunctionEnd
  5554. %in = OpExtInst %void %ext )" +
  5555. ext_inst + " %int_0 %int_0 " + extra;
  5556. CompileSuccessfully(text);
  5557. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5558. EXPECT_THAT(getDiagnosticString(),
  5559. HasSubstr("Kernel must be a Kernel extended instruction"));
  5560. }
  5561. TEST_P(ArgumentBasics, KernelFromDifferentImport) {
  5562. const std::string ext_inst = std::get<0>(GetParam());
  5563. const std::string extra = std::get<1>(GetParam());
  5564. const std::string text = R"(
  5565. OpCapability Shader
  5566. OpExtension "SPV_KHR_non_semantic_info"
  5567. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5568. %ext2 = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5569. OpMemoryModel Logical GLSL450
  5570. OpEntryPoint GLCompute %foo "foo"
  5571. OpExecutionMode %foo LocalSize 1 1 1
  5572. %foo_name = OpString "foo"
  5573. %void = OpTypeVoid
  5574. %int = OpTypeInt 32 0
  5575. %int_0 = OpConstant %int 0
  5576. %int_4 = OpConstant %int 4
  5577. %void_fn = OpTypeFunction %void
  5578. %foo = OpFunction %void None %void_fn
  5579. %entry = OpLabel
  5580. OpReturn
  5581. OpFunctionEnd
  5582. %decl = OpExtInst %void %ext2 Kernel %foo %foo_name
  5583. %in = OpExtInst %void %ext )" +
  5584. ext_inst + " %decl %int_0 " + extra;
  5585. CompileSuccessfully(text);
  5586. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5587. EXPECT_THAT(
  5588. getDiagnosticString(),
  5589. HasSubstr("Kernel must be from the same extended instruction import"));
  5590. }
  5591. TEST_P(ArgumentBasics, KernelWrongExtendedInstruction) {
  5592. const std::string ext_inst = std::get<0>(GetParam());
  5593. const std::string extra = std::get<1>(GetParam());
  5594. const std::string text = R"(
  5595. OpCapability Shader
  5596. OpExtension "SPV_KHR_non_semantic_info"
  5597. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5598. OpMemoryModel Logical GLSL450
  5599. OpEntryPoint GLCompute %foo "foo"
  5600. OpExecutionMode %foo LocalSize 1 1 1
  5601. %foo_name = OpString "foo"
  5602. %void = OpTypeVoid
  5603. %int = OpTypeInt 32 0
  5604. %int_0 = OpConstant %int 0
  5605. %int_4 = OpConstant %int 4
  5606. %void_fn = OpTypeFunction %void
  5607. %foo = OpFunction %void None %void_fn
  5608. %entry = OpLabel
  5609. OpReturn
  5610. OpFunctionEnd
  5611. %decl = OpExtInst %void %ext ArgumentInfo %foo_name
  5612. %in = OpExtInst %void %ext )" +
  5613. ext_inst + " %decl %int_0 " + extra;
  5614. CompileSuccessfully(text);
  5615. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5616. EXPECT_THAT(getDiagnosticString(),
  5617. HasSubstr("Kernel must be a Kernel extended instruction"));
  5618. }
  5619. TEST_P(ArgumentBasics, ArgumentInfo) {
  5620. const std::string ext_inst = std::get<0>(GetParam());
  5621. const std::string operands = std::get<1>(GetParam());
  5622. const std::string text = R"(
  5623. OpCapability Shader
  5624. OpExtension "SPV_KHR_non_semantic_info"
  5625. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5626. OpMemoryModel Logical GLSL450
  5627. OpEntryPoint GLCompute %foo "foo"
  5628. OpExecutionMode %foo LocalSize 1 1 1
  5629. %foo_name = OpString "foo"
  5630. %in_name = OpString "in"
  5631. %void = OpTypeVoid
  5632. %int = OpTypeInt 32 0
  5633. %int_0 = OpConstant %int 0
  5634. %int_4 = OpConstant %int 4
  5635. %void_fn = OpTypeFunction %void
  5636. %foo = OpFunction %void None %void_fn
  5637. %entry = OpLabel
  5638. OpReturn
  5639. OpFunctionEnd
  5640. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  5641. %info = OpExtInst %void %ext ArgumentInfo %in_name
  5642. %in = OpExtInst %void %ext )" +
  5643. ext_inst + " %decl %int_0 " + operands + " %info";
  5644. CompileSuccessfully(text);
  5645. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  5646. }
  5647. TEST_P(ArgumentBasics, ArgumentInfoNotAnExtendedInstruction) {
  5648. const std::string ext_inst = std::get<0>(GetParam());
  5649. const std::string operands = std::get<1>(GetParam());
  5650. const std::string text = R"(
  5651. OpCapability Shader
  5652. OpExtension "SPV_KHR_non_semantic_info"
  5653. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5654. OpMemoryModel Logical GLSL450
  5655. OpEntryPoint GLCompute %foo "foo"
  5656. OpExecutionMode %foo LocalSize 1 1 1
  5657. %foo_name = OpString "foo"
  5658. %void = OpTypeVoid
  5659. %int = OpTypeInt 32 0
  5660. %int_0 = OpConstant %int 0
  5661. %int_4 = OpConstant %int 4
  5662. %void_fn = OpTypeFunction %void
  5663. %foo = OpFunction %void None %void_fn
  5664. %entry = OpLabel
  5665. OpReturn
  5666. OpFunctionEnd
  5667. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  5668. %in = OpExtInst %void %ext )" +
  5669. ext_inst + " %decl %int_0 " + operands + " %int_0";
  5670. CompileSuccessfully(text);
  5671. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5672. EXPECT_THAT(
  5673. getDiagnosticString(),
  5674. HasSubstr("ArgInfo must be an ArgumentInfo extended instruction"));
  5675. }
  5676. TEST_P(ArgumentBasics, ArgumentInfoFromDifferentImport) {
  5677. const std::string ext_inst = std::get<0>(GetParam());
  5678. const std::string operands = std::get<1>(GetParam());
  5679. const std::string text = R"(
  5680. OpCapability Shader
  5681. OpExtension "SPV_KHR_non_semantic_info"
  5682. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5683. %ext2 = OpExtInstImport "NonSemantic.ClspvReflection.5"
  5684. OpMemoryModel Logical GLSL450
  5685. OpEntryPoint GLCompute %foo "foo"
  5686. OpExecutionMode %foo LocalSize 1 1 1
  5687. %foo_name = OpString "foo"
  5688. %in_name = OpString "in"
  5689. %void = OpTypeVoid
  5690. %int = OpTypeInt 32 0
  5691. %int_0 = OpConstant %int 0
  5692. %int_4 = OpConstant %int 4
  5693. %void_fn = OpTypeFunction %void
  5694. %foo = OpFunction %void None %void_fn
  5695. %entry = OpLabel
  5696. OpReturn
  5697. OpFunctionEnd
  5698. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  5699. %info = OpExtInst %void %ext2 ArgumentInfo %in_name
  5700. %in = OpExtInst %void %ext )" +
  5701. ext_inst + " %decl %int_0 " + operands + " %info";
  5702. CompileSuccessfully(text);
  5703. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  5704. EXPECT_THAT(
  5705. getDiagnosticString(),
  5706. HasSubstr("ArgInfo must be from the same extended instruction import"));
  5707. }
  5708. using Uint32Constant =
  5709. spvtest::ValidateBase<std::pair<std::string, std::string>>;
  5710. INSTANTIATE_TEST_SUITE_P(
  5711. ValidateClspvReflectionUint32Constants, Uint32Constant,
  5712. ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
  5713. std::make_pair("ArgumentStorageBuffer %decl %float_0 %int_0 %int_0",
  5714. "Ordinal"),
  5715. std::make_pair("ArgumentStorageBuffer %decl %null %int_0 %int_0",
  5716. "Ordinal"),
  5717. std::make_pair("ArgumentStorageBuffer %decl %int_0 %float_0 %int_0",
  5718. "DescriptorSet"),
  5719. std::make_pair("ArgumentStorageBuffer %decl %int_0 %null %int_0",
  5720. "DescriptorSet"),
  5721. std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %float_0",
  5722. "Binding"),
  5723. std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %null",
  5724. "Binding"),
  5725. std::make_pair("ArgumentUniform %decl %float_0 %int_0 %int_0",
  5726. "Ordinal"),
  5727. std::make_pair("ArgumentUniform %decl %null %int_0 %int_0", "Ordinal"),
  5728. std::make_pair("ArgumentUniform %decl %int_0 %float_0 %int_0",
  5729. "DescriptorSet"),
  5730. std::make_pair("ArgumentUniform %decl %int_0 %null %int_0",
  5731. "DescriptorSet"),
  5732. std::make_pair("ArgumentUniform %decl %int_0 %int_0 %float_0",
  5733. "Binding"),
  5734. std::make_pair("ArgumentUniform %decl %int_0 %int_0 %null", "Binding"),
  5735. std::make_pair("ArgumentSampledImage %decl %float_0 %int_0 %int_0",
  5736. "Ordinal"),
  5737. std::make_pair("ArgumentSampledImage %decl %null %int_0 %int_0",
  5738. "Ordinal"),
  5739. std::make_pair("ArgumentSampledImage %decl %int_0 %float_0 %int_0",
  5740. "DescriptorSet"),
  5741. std::make_pair("ArgumentSampledImage %decl %int_0 %null %int_0",
  5742. "DescriptorSet"),
  5743. std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %float_0",
  5744. "Binding"),
  5745. std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %null",
  5746. "Binding"),
  5747. std::make_pair("ArgumentStorageImage %decl %float_0 %int_0 %int_0",
  5748. "Ordinal"),
  5749. std::make_pair("ArgumentStorageImage %decl %null %int_0 %int_0",
  5750. "Ordinal"),
  5751. std::make_pair("ArgumentStorageImage %decl %int_0 %float_0 %int_0",
  5752. "DescriptorSet"),
  5753. std::make_pair("ArgumentStorageImage %decl %int_0 %null %int_0",
  5754. "DescriptorSet"),
  5755. std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %float_0",
  5756. "Binding"),
  5757. std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %null",
  5758. "Binding"),
  5759. std::make_pair("ArgumentSampler %decl %float_0 %int_0 %int_0",
  5760. "Ordinal"),
  5761. std::make_pair("ArgumentSampler %decl %null %int_0 %int_0", "Ordinal"),
  5762. std::make_pair("ArgumentSampler %decl %int_0 %float_0 %int_0",
  5763. "DescriptorSet"),
  5764. std::make_pair("ArgumentSampler %decl %int_0 %null %int_0",
  5765. "DescriptorSet"),
  5766. std::make_pair("ArgumentSampler %decl %int_0 %int_0 %float_0",
  5767. "Binding"),
  5768. std::make_pair("ArgumentSampler %decl %int_0 %int_0 %null", "Binding"),
  5769. std::make_pair("ArgumentPodStorageBuffer %decl %float_0 %int_0 %int_0 "
  5770. "%int_0 %int_4",
  5771. "Ordinal"),
  5772. std::make_pair(
  5773. "ArgumentPodStorageBuffer %decl %null %int_0 %int_0 %int_0 %int_4",
  5774. "Ordinal"),
  5775. std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %float_0 %int_0 "
  5776. "%int_0 %int_4",
  5777. "DescriptorSet"),
  5778. std::make_pair(
  5779. "ArgumentPodStorageBuffer %decl %int_0 %null %int_0 %int_0 %int_4",
  5780. "DescriptorSet"),
  5781. std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %float_0 "
  5782. "%int_0 %int_4",
  5783. "Binding"),
  5784. std::make_pair(
  5785. "ArgumentPodStorageBuffer %decl %int_0 %int_0 %null %int_0 %int_4",
  5786. "Binding"),
  5787. std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 "
  5788. "%float_0 %int_4",
  5789. "Offset"),
  5790. std::make_pair(
  5791. "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %null %int_4",
  5792. "Offset"),
  5793. std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 "
  5794. "%int_0 %float_0",
  5795. "Size"),
  5796. std::make_pair(
  5797. "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %int_0 %null",
  5798. "Size"),
  5799. std::make_pair(
  5800. "ArgumentPodUniform %decl %float_0 %int_0 %int_0 %int_0 %int_4",
  5801. "Ordinal"),
  5802. std::make_pair(
  5803. "ArgumentPodUniform %decl %null %int_0 %int_0 %int_0 %int_4",
  5804. "Ordinal"),
  5805. std::make_pair(
  5806. "ArgumentPodUniform %decl %int_0 %float_0 %int_0 %int_0 %int_4",
  5807. "DescriptorSet"),
  5808. std::make_pair(
  5809. "ArgumentPodUniform %decl %int_0 %null %int_0 %int_0 %int_4",
  5810. "DescriptorSet"),
  5811. std::make_pair(
  5812. "ArgumentPodUniform %decl %int_0 %int_0 %float_0 %int_0 %int_4",
  5813. "Binding"),
  5814. std::make_pair(
  5815. "ArgumentPodUniform %decl %int_0 %int_0 %null %int_0 %int_4",
  5816. "Binding"),
  5817. std::make_pair(
  5818. "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %float_0 %int_4",
  5819. "Offset"),
  5820. std::make_pair(
  5821. "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %null %int_4",
  5822. "Offset"),
  5823. std::make_pair(
  5824. "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %float_0",
  5825. "Size"),
  5826. std::make_pair(
  5827. "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %null",
  5828. "Size"),
  5829. std::make_pair("ArgumentPodPushConstant %decl %float_0 %int_0 %int_4",
  5830. "Ordinal"),
  5831. std::make_pair("ArgumentPodPushConstant %decl %null %int_0 %int_4",
  5832. "Ordinal"),
  5833. std::make_pair("ArgumentPodPushConstant %decl %int_0 %float_0 %int_4",
  5834. "Offset"),
  5835. std::make_pair("ArgumentPodPushConstant %decl %int_0 %null %int_4",
  5836. "Offset"),
  5837. std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %float_0",
  5838. "Size"),
  5839. std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %null",
  5840. "Size"),
  5841. std::make_pair("ArgumentWorkgroup %decl %float_0 %int_0 %int_4",
  5842. "Ordinal"),
  5843. std::make_pair("ArgumentWorkgroup %decl %null %int_0 %int_4",
  5844. "Ordinal"),
  5845. std::make_pair("ArgumentWorkgroup %decl %int_0 %float_0 %int_4",
  5846. "SpecId"),
  5847. std::make_pair("ArgumentWorkgroup %decl %int_0 %null %int_4", "SpecId"),
  5848. std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %float_0",
  5849. "ElemSize"),
  5850. std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %null",
  5851. "ElemSize"),
  5852. std::make_pair("SpecConstantWorkgroupSize %float_0 %int_0 %int_4", "X"),
  5853. std::make_pair("SpecConstantWorkgroupSize %null %int_0 %int_4", "X"),
  5854. std::make_pair("SpecConstantWorkgroupSize %int_0 %float_0 %int_4", "Y"),
  5855. std::make_pair("SpecConstantWorkgroupSize %int_0 %null %int_4", "Y"),
  5856. std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %float_0", "Z"),
  5857. std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %null", "Z"),
  5858. std::make_pair("SpecConstantGlobalOffset %float_0 %int_0 %int_4", "X"),
  5859. std::make_pair("SpecConstantGlobalOffset %null %int_0 %int_4", "X"),
  5860. std::make_pair("SpecConstantGlobalOffset %int_0 %float_0 %int_4", "Y"),
  5861. std::make_pair("SpecConstantGlobalOffset %int_0 %null %int_4", "Y"),
  5862. std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %float_0", "Z"),
  5863. std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %null", "Z"),
  5864. std::make_pair("SpecConstantWorkDim %float_0", "Dim"),
  5865. std::make_pair("SpecConstantWorkDim %null", "Dim"),
  5866. std::make_pair("PushConstantGlobalOffset %float_0 %int_0", "Offset"),
  5867. std::make_pair("PushConstantGlobalOffset %null %int_0", "Offset"),
  5868. std::make_pair("PushConstantGlobalOffset %int_0 %float_0", "Size"),
  5869. std::make_pair("PushConstantGlobalOffset %int_0 %null", "Size"),
  5870. std::make_pair("PushConstantEnqueuedLocalSize %float_0 %int_0",
  5871. "Offset"),
  5872. std::make_pair("PushConstantEnqueuedLocalSize %null %int_0", "Offset"),
  5873. std::make_pair("PushConstantEnqueuedLocalSize %int_0 %float_0", "Size"),
  5874. std::make_pair("PushConstantEnqueuedLocalSize %int_0 %null", "Size"),
  5875. std::make_pair("PushConstantGlobalSize %float_0 %int_0", "Offset"),
  5876. std::make_pair("PushConstantGlobalSize %null %int_0", "Offset"),
  5877. std::make_pair("PushConstantGlobalSize %int_0 %float_0", "Size"),
  5878. std::make_pair("PushConstantGlobalSize %int_0 %null", "Size"),
  5879. std::make_pair("PushConstantRegionOffset %float_0 %int_0", "Offset"),
  5880. std::make_pair("PushConstantRegionOffset %null %int_0", "Offset"),
  5881. std::make_pair("PushConstantRegionOffset %int_0 %float_0", "Size"),
  5882. std::make_pair("PushConstantRegionOffset %int_0 %null", "Size"),
  5883. std::make_pair("PushConstantNumWorkgroups %float_0 %int_0", "Offset"),
  5884. std::make_pair("PushConstantNumWorkgroups %null %int_0", "Offset"),
  5885. std::make_pair("PushConstantNumWorkgroups %int_0 %float_0", "Size"),
  5886. std::make_pair("PushConstantNumWorkgroups %int_0 %null", "Size"),
  5887. std::make_pair("PushConstantRegionGroupOffset %float_0 %int_0",
  5888. "Offset"),
  5889. std::make_pair("PushConstantRegionGroupOffset %null %int_0", "Offset"),
  5890. std::make_pair("PushConstantRegionGroupOffset %int_0 %float_0", "Size"),
  5891. std::make_pair("PushConstantRegionGroupOffset %int_0 %null", "Size"),
  5892. std::make_pair("ConstantDataStorageBuffer %float_0 %int_0 %data",
  5893. "DescriptorSet"),
  5894. std::make_pair("ConstantDataStorageBuffer %null %int_0 %data",
  5895. "DescriptorSet"),
  5896. std::make_pair("ConstantDataStorageBuffer %int_0 %float_0 %data",
  5897. "Binding"),
  5898. std::make_pair("ConstantDataStorageBuffer %int_0 %null %data",
  5899. "Binding"),
  5900. std::make_pair("ConstantDataUniform %float_0 %int_0 %data",
  5901. "DescriptorSet"),
  5902. std::make_pair("ConstantDataUniform %null %int_0 %data",
  5903. "DescriptorSet"),
  5904. std::make_pair("ConstantDataUniform %int_0 %float_0 %data", "Binding"),
  5905. std::make_pair("ConstantDataUniform %int_0 %null %data", "Binding"),
  5906. std::make_pair("LiteralSampler %float_0 %int_0 %int_4",
  5907. "DescriptorSet"),
  5908. std::make_pair("LiteralSampler %null %int_0 %int_4", "DescriptorSet"),
  5909. std::make_pair("LiteralSampler %int_0 %float_0 %int_4", "Binding"),
  5910. std::make_pair("LiteralSampler %int_0 %null %int_4", "Binding"),
  5911. std::make_pair("LiteralSampler %int_0 %int_0 %float_0", "Mask"),
  5912. std::make_pair("LiteralSampler %int_0 %int_0 %null", "Mask"),
  5913. std::make_pair(
  5914. "PropertyRequiredWorkgroupSize %decl %float_0 %int_1 %int_4", "X"),
  5915. std::make_pair(
  5916. "PropertyRequiredWorkgroupSize %decl %null %int_1 %int_4", "X"),
  5917. std::make_pair(
  5918. "PropertyRequiredWorkgroupSize %decl %int_1 %float_0 %int_4", "Y"),
  5919. std::make_pair(
  5920. "PropertyRequiredWorkgroupSize %decl %int_1 %null %int_4", "Y"),
  5921. std::make_pair(
  5922. "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %float_0", "Z"),
  5923. std::make_pair(
  5924. "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %null", "Z"),
  5925. std::make_pair("SpecConstantSubgroupMaxSize %float_0", "Size"),
  5926. std::make_pair("SpecConstantSubgroupMaxSize %null", "Size"),
  5927. std::make_pair(
  5928. "ArgumentPointerPushConstant %decl %float_0 %int_0 %int_0",
  5929. "Ordinal"),
  5930. std::make_pair("ArgumentPointerPushConstant %decl %null %int_0 %int_0",
  5931. "Ordinal"),
  5932. std::make_pair(
  5933. "ArgumentPointerPushConstant %decl %int_0 %float_0 %int_0",
  5934. "Offset"),
  5935. std::make_pair("ArgumentPointerPushConstant %decl %int_0 %null %int_0",
  5936. "Offset"),
  5937. std::make_pair(
  5938. "ArgumentPointerPushConstant %decl %int_0 %int_0 %float_0", "Size"),
  5939. std::make_pair("ArgumentPointerPushConstant %decl %int_0 %int_0 %null",
  5940. "Size"),
  5941. std::make_pair(
  5942. "ArgumentPointerUniform %decl %float_0 %int_0 %int_0 %int_0 %int_4",
  5943. "Ordinal"),
  5944. std::make_pair(
  5945. "ArgumentPointerUniform %decl %null %int_0 %int_0 %int_0 %int_4",
  5946. "Ordinal"),
  5947. std::make_pair(
  5948. "ArgumentPointerUniform %decl %int_0 %float_0 %int_0 %int_0 %int_4",
  5949. "DescriptorSet"),
  5950. std::make_pair(
  5951. "ArgumentPointerUniform %decl %int_0 %null %int_0 %int_0 %int_4",
  5952. "DescriptorSet"),
  5953. std::make_pair(
  5954. "ArgumentPointerUniform %decl %int_0 %int_0 %float_0 %int_0 %int_4",
  5955. "Binding"),
  5956. std::make_pair(
  5957. "ArgumentPointerUniform %decl %int_0 %int_0 %null %int_0 %int_4",
  5958. "Binding"),
  5959. std::make_pair(
  5960. "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %float_0 %int_4",
  5961. "Offset"),
  5962. std::make_pair(
  5963. "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %null %int_4",
  5964. "Offset"),
  5965. std::make_pair(
  5966. "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %int_0 %float_0",
  5967. "Size"),
  5968. std::make_pair(
  5969. "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %int_0 %null",
  5970. "Size"),
  5971. std::make_pair(
  5972. "ProgramScopeVariablesStorageBuffer %float_0 %int_0 %data",
  5973. "DescriptorSet"),
  5974. std::make_pair("ProgramScopeVariablesStorageBuffer %null %int_0 %data",
  5975. "DescriptorSet"),
  5976. std::make_pair(
  5977. "ProgramScopeVariablesStorageBuffer %int_0 %float_0 %data",
  5978. "Binding"),
  5979. std::make_pair("ProgramScopeVariablesStorageBuffer %int_0 %null %data",
  5980. "Binding"),
  5981. std::make_pair(
  5982. "ProgramScopeVariablePointerRelocation %float_0 %int_0 %int_4",
  5983. "ObjectOffset"),
  5984. std::make_pair(
  5985. "ProgramScopeVariablePointerRelocation %null %int_0 %int_4",
  5986. "ObjectOffset"),
  5987. std::make_pair(
  5988. "ProgramScopeVariablePointerRelocation %int_0 %float_0 %int_4",
  5989. "PointerOffset"),
  5990. std::make_pair(
  5991. "ProgramScopeVariablePointerRelocation %int_0 %null %int_4",
  5992. "PointerOffset"),
  5993. std::make_pair(
  5994. "ProgramScopeVariablePointerRelocation %int_0 %int_0 %float_0",
  5995. "PointerSize"),
  5996. std::make_pair(
  5997. "ProgramScopeVariablePointerRelocation %int_0 %int_0 %null",
  5998. "PointerSize"),
  5999. std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl "
  6000. "%float_0 %int_0 %int_4",
  6001. "Ordinal"),
  6002. std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %null "
  6003. "%int_0 %int_4",
  6004. "Ordinal"),
  6005. std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 "
  6006. "%float_0 %int_4",
  6007. "Offset"),
  6008. std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 "
  6009. "%null %int_4",
  6010. "Offset"),
  6011. std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 "
  6012. "%int_0 %float_0",
  6013. "Size"),
  6014. std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 "
  6015. "%int_0 %null",
  6016. "Size"),
  6017. std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl "
  6018. "%float_0 %int_0 %int_4",
  6019. "Ordinal"),
  6020. std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl "
  6021. "%null %int_0 %int_4",
  6022. "Ordinal"),
  6023. std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl "
  6024. "%int_0 %float_0 %int_4",
  6025. "Offset"),
  6026. std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl "
  6027. "%int_0 %null %int_4",
  6028. "Offset"),
  6029. std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl "
  6030. "%int_0 %int_0 %float_0",
  6031. "Size"),
  6032. std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl "
  6033. "%int_0 %int_0 %null",
  6034. "Size"),
  6035. std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %float_0 "
  6036. "%int_0 %int_0 %int_0 %int_4",
  6037. "Ordinal"),
  6038. std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %null "
  6039. "%int_0 %int_0 %int_0 %int_4",
  6040. "Ordinal"),
  6041. std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 "
  6042. "%float_0 %int_0 %int_0 %int_4",
  6043. "DescriptorSet"),
  6044. std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 "
  6045. "%null %int_0 %int_0 %int_4",
  6046. "DescriptorSet"),
  6047. std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 "
  6048. "%int_0 %float_0 %int_0 %int_4",
  6049. "Binding"),
  6050. std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 "
  6051. "%int_0 %null %int_0 %int_4",
  6052. "Binding"),
  6053. std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 "
  6054. "%int_0 %int_0 %float_0 %int_4",
  6055. "Offset"),
  6056. std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 "
  6057. "%int_0 %int_0 %null %int_4",
  6058. "Offset"),
  6059. std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 "
  6060. "%int_0 %int_0 %int_0 %float_0",
  6061. "Size"),
  6062. std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 "
  6063. "%int_0 %int_0 %int_0 %null",
  6064. "Size"),
  6065. std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %float_0 "
  6066. "%int_0 %int_0 %int_0 %int_4",
  6067. "Ordinal"),
  6068. std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %null "
  6069. "%int_0 %int_0 %int_0 %int_4",
  6070. "Ordinal"),
  6071. std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 "
  6072. "%float_0 %int_0 %int_0 %int_4",
  6073. "DescriptorSet"),
  6074. std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 "
  6075. "%null %int_0 %int_0 %int_4",
  6076. "DescriptorSet"),
  6077. std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 "
  6078. "%int_0 %float_0 %int_0 %int_4",
  6079. "Binding"),
  6080. std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 "
  6081. "%int_0 %null %int_0 %int_4",
  6082. "Binding"),
  6083. std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 "
  6084. "%int_0 %int_0 %float_0 %int_4",
  6085. "Offset"),
  6086. std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 "
  6087. "%int_0 %int_0 %null %int_4",
  6088. "Offset"),
  6089. std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 "
  6090. "%int_0 %int_0 %int_0 %float_0",
  6091. "Size"),
  6092. std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 "
  6093. "%int_0 %int_0 %int_0 %null",
  6094. "Size"),
  6095. std::make_pair(
  6096. "ArgumentStorageTexelBuffer %decl %float_0 %int_0 %int_0",
  6097. "Ordinal"),
  6098. std::make_pair("ArgumentStorageTexelBuffer %decl %null %int_0 %int_0",
  6099. "Ordinal"),
  6100. std::make_pair(
  6101. "ArgumentStorageTexelBuffer %decl %int_0 %float_0 %int_0",
  6102. "DescriptorSet"),
  6103. std::make_pair("ArgumentStorageTexelBuffer %decl %int_0 %null %int_0",
  6104. "DescriptorSet"),
  6105. std::make_pair(
  6106. "ArgumentStorageTexelBuffer %decl %int_0 %int_0 %float_0",
  6107. "Binding"),
  6108. std::make_pair("ArgumentStorageTexelBuffer %decl %int_0 %int_0 %null",
  6109. "Binding"),
  6110. std::make_pair(
  6111. "ArgumentUniformTexelBuffer %decl %float_0 %int_0 %int_0",
  6112. "Ordinal"),
  6113. std::make_pair("ArgumentUniformTexelBuffer %decl %null %int_0 %int_0",
  6114. "Ordinal"),
  6115. std::make_pair(
  6116. "ArgumentUniformTexelBuffer %decl %int_0 %float_0 %int_0",
  6117. "DescriptorSet"),
  6118. std::make_pair("ArgumentUniformTexelBuffer %decl %int_0 %null %int_0",
  6119. "DescriptorSet"),
  6120. std::make_pair(
  6121. "ArgumentUniformTexelBuffer %decl %int_0 %int_0 %float_0",
  6122. "Binding"),
  6123. std::make_pair("ArgumentUniformTexelBuffer %decl %int_0 %int_0 %null",
  6124. "Binding"),
  6125. std::make_pair("ConstantDataPointerPushConstant %float_0 %int_4 %data",
  6126. "Offset"),
  6127. std::make_pair("ConstantDataPointerPushConstant %null %int_4 %data",
  6128. "Offset"),
  6129. std::make_pair("ConstantDataPointerPushConstant %int_0 %float_0 %data",
  6130. "Size"),
  6131. std::make_pair("ConstantDataPointerPushConstant %int_0 %null %data",
  6132. "Size"),
  6133. std::make_pair(
  6134. "ProgramScopeVariablePointerPushConstant %float_0 %int_4 %data",
  6135. "Offset"),
  6136. std::make_pair(
  6137. "ProgramScopeVariablePointerPushConstant %null %int_4 %data",
  6138. "Offset"),
  6139. std::make_pair(
  6140. "ProgramScopeVariablePointerPushConstant %int_0 %float_0 %data",
  6141. "Size"),
  6142. std::make_pair(
  6143. "ProgramScopeVariablePointerPushConstant %int_0 %null %data",
  6144. "Size"),
  6145. std::make_pair("PrintfInfo %float_0 %data %int_0 %int_0 %int_0",
  6146. "PrintfID"),
  6147. std::make_pair("PrintfInfo %null %data %int_0 %int_0 %int_0",
  6148. "PrintfID"),
  6149. std::make_pair("PrintfInfo %int_0 %data %float_0 %int_0 %int_0",
  6150. "ArgumentSizes"),
  6151. std::make_pair("PrintfInfo %int_0 %data %null %int_0 %int_0",
  6152. "ArgumentSizes"),
  6153. std::make_pair("PrintfInfo %int_0 %data %int_0 %float_0 %int_0",
  6154. "ArgumentSizes"),
  6155. std::make_pair("PrintfInfo %int_0 %data %int_0 %null %int_0",
  6156. "ArgumentSizes"),
  6157. std::make_pair("PrintfInfo %int_0 %data %int_0 %int_0 %null",
  6158. "ArgumentSizes"),
  6159. std::make_pair("PrintfInfo %int_0 %data %int_0 %int_0 %float_0",
  6160. "ArgumentSizes"),
  6161. std::make_pair("PrintfInfo %int_0 %data %int_0 %float_0",
  6162. "ArgumentSizes"),
  6163. std::make_pair("PrintfInfo %int_0 %data %int_0 %null", "ArgumentSizes"),
  6164. std::make_pair("PrintfBufferStorageBuffer %float_0 %int_0 %int_4",
  6165. "DescriptorSet"),
  6166. std::make_pair("PrintfBufferStorageBuffer %null %int_0 %int_4",
  6167. "DescriptorSet"),
  6168. std::make_pair("PrintfBufferStorageBuffer %int_0 %float_0 %int_4",
  6169. "Binding"),
  6170. std::make_pair("PrintfBufferStorageBuffer %int_0 %null %int_4",
  6171. "Binding"),
  6172. std::make_pair("PrintfBufferStorageBuffer %int_0 %int_0 %float_0",
  6173. "Size"),
  6174. std::make_pair("PrintfBufferStorageBuffer %int_0 %int_0 %null", "Size"),
  6175. std::make_pair("PrintfBufferPointerPushConstant %float_0 %int_0 %int_4",
  6176. "Offset"),
  6177. std::make_pair("PrintfBufferPointerPushConstant %null %int_0 %int_4",
  6178. "Offset"),
  6179. std::make_pair("PrintfBufferPointerPushConstant %int_0 %float_0 %int_4",
  6180. "Size"),
  6181. std::make_pair("PrintfBufferPointerPushConstant %int_0 %null %int_4",
  6182. "Size"),
  6183. std::make_pair("PrintfBufferPointerPushConstant %int_0 %int_0 %float_0",
  6184. "BufferSize"),
  6185. std::make_pair("PrintfBufferPointerPushConstant %int_0 %int_0 %null",
  6186. "BufferSize")}));
  6187. TEST_P(Uint32Constant, Invalid) {
  6188. const std::string ext_inst = std::get<0>(GetParam());
  6189. const std::string name = std::get<1>(GetParam());
  6190. const std::string text = R"(
  6191. OpCapability Shader
  6192. OpExtension "SPV_KHR_non_semantic_info"
  6193. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  6194. OpMemoryModel Logical GLSL450
  6195. OpEntryPoint GLCompute %foo "foo"
  6196. OpExecutionMode %foo LocalSize 1 1 1
  6197. %foo_name = OpString "foo"
  6198. %data = OpString "1234"
  6199. %void = OpTypeVoid
  6200. %int = OpTypeInt 32 0
  6201. %int_0 = OpConstant %int 0
  6202. %int_1 = OpConstant %int 1
  6203. %int_4 = OpConstant %int 4
  6204. %null = OpConstantNull %int
  6205. %float = OpTypeFloat 32
  6206. %float_0 = OpConstant %float 0
  6207. %void_fn = OpTypeFunction %void
  6208. %foo = OpFunction %void None %void_fn
  6209. %entry = OpLabel
  6210. OpReturn
  6211. OpFunctionEnd
  6212. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  6213. %inst = OpExtInst %void %ext )" +
  6214. ext_inst;
  6215. CompileSuccessfully(text);
  6216. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6217. EXPECT_THAT(
  6218. getDiagnosticString(),
  6219. HasSubstr(name + " must be a 32-bit unsigned integer OpConstant"));
  6220. }
  6221. using StringOperand =
  6222. spvtest::ValidateBase<std::pair<std::string, std::string>>;
  6223. INSTANTIATE_TEST_SUITE_P(
  6224. ValidateClspvReflectionStringOperands, StringOperand,
  6225. ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
  6226. std::make_pair("ConstantDataStorageBuffer %int_0 %int_0 %int_0",
  6227. "Data"),
  6228. std::make_pair("ConstantDataUniform %int_0 %int_0 %int_0", "Data"),
  6229. std::make_pair(
  6230. "ProgramScopeVariablesStorageBuffer %int_0 %int_0 %int_0", "Data"),
  6231. std::make_pair("ConstantDataPointerPushConstant %int_0 %int_0 %int_0",
  6232. "Data"),
  6233. std::make_pair(
  6234. "ProgramScopeVariablePointerPushConstant %int_0 %int_0 %int_0",
  6235. "Data"),
  6236. std::make_pair("PrintfInfo %int_0 %int_0", "FormatString")}));
  6237. TEST_P(StringOperand, Invalid) {
  6238. const std::string ext_inst = std::get<0>(GetParam());
  6239. const std::string name = std::get<1>(GetParam());
  6240. const std::string text = R"(
  6241. OpCapability Shader
  6242. OpExtension "SPV_KHR_non_semantic_info"
  6243. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  6244. OpMemoryModel Logical GLSL450
  6245. OpEntryPoint GLCompute %foo "foo"
  6246. OpExecutionMode %foo LocalSize 1 1 1
  6247. %foo_name = OpString "foo"
  6248. %data = OpString "1234"
  6249. %void = OpTypeVoid
  6250. %int = OpTypeInt 32 0
  6251. %int_0 = OpConstant %int 0
  6252. %int_1 = OpConstant %int 1
  6253. %int_4 = OpConstant %int 4
  6254. %null = OpConstantNull %int
  6255. %float = OpTypeFloat 32
  6256. %float_0 = OpConstant %float 0
  6257. %void_fn = OpTypeFunction %void
  6258. %foo = OpFunction %void None %void_fn
  6259. %entry = OpLabel
  6260. OpReturn
  6261. OpFunctionEnd
  6262. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  6263. %inst = OpExtInst %void %ext )" +
  6264. ext_inst;
  6265. CompileSuccessfully(text);
  6266. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6267. EXPECT_THAT(getDiagnosticString(), HasSubstr(name + " must be an OpString"));
  6268. }
  6269. using VersionCheck = spvtest::ValidateBase<std::pair<std::string, uint32_t>>;
  6270. INSTANTIATE_TEST_SUITE_P(
  6271. ValidateClspvReflectionVersionCheck, VersionCheck,
  6272. ::testing::ValuesIn(std::vector<std::pair<std::string, uint32_t>>{
  6273. std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %int_0", 1),
  6274. std::make_pair("ArgumentUniform %decl %int_0 %int_0 %int_0", 1),
  6275. std::make_pair(
  6276. "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %int_0 %int_0",
  6277. 1),
  6278. std::make_pair(
  6279. "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %int_0", 1),
  6280. std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %int_0", 1),
  6281. std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %int_0", 1),
  6282. std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %int_0", 1),
  6283. std::make_pair("ArgumentSampler %decl %int_0 %int_0 %int_0", 1),
  6284. std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %int_0", 1),
  6285. std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %int_0", 1),
  6286. std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %int_0", 1),
  6287. std::make_pair("SpecConstantWorkDim %int_0", 1),
  6288. std::make_pair("PushConstantGlobalOffset %int_0 %int_0", 1),
  6289. std::make_pair("PushConstantEnqueuedLocalSize %int_0 %int_0", 1),
  6290. std::make_pair("PushConstantGlobalSize %int_0 %int_0", 1),
  6291. std::make_pair("PushConstantRegionOffset %int_0 %int_0", 1),
  6292. std::make_pair("PushConstantNumWorkgroups %int_0 %int_0", 1),
  6293. std::make_pair("PushConstantRegionGroupOffset %int_0 %int_0", 1),
  6294. std::make_pair("ConstantDataStorageBuffer %int_0 %int_0 %data", 1),
  6295. std::make_pair("ConstantDataUniform %int_0 %int_0 %data", 1),
  6296. std::make_pair("LiteralSampler %int_0 %int_0 %int_0", 1),
  6297. std::make_pair(
  6298. "PropertyRequiredWorkgroupSize %decl %int_0 %int_0 %int_0", 1),
  6299. std::make_pair("SpecConstantSubgroupMaxSize %int_0", 2),
  6300. std::make_pair("ArgumentPointerPushConstant %decl %int_0 %int_0 %int_0",
  6301. 3),
  6302. std::make_pair(
  6303. "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %int_0 %int_0",
  6304. 3),
  6305. std::make_pair("ProgramScopeVariablesStorageBuffer %int_0 %int_0 %data",
  6306. 3),
  6307. std::make_pair(
  6308. "ProgramScopeVariablePointerRelocation %int_0 %int_0 %int_0", 3),
  6309. std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 "
  6310. "%int_0 %int_0",
  6311. 3),
  6312. std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl "
  6313. "%int_0 %int_0 %int_0",
  6314. 3),
  6315. std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 "
  6316. "%int_0 %int_0 %int_0 %int_0",
  6317. 3),
  6318. std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 "
  6319. "%int_0 %int_0 %int_0 %int_0",
  6320. 3),
  6321. std::make_pair("ArgumentStorageTexelBuffer %decl %int_0 %int_0 %int_0",
  6322. 4),
  6323. std::make_pair("ArgumentUniformTexelBuffer %decl %int_0 %int_0 %int_0",
  6324. 4),
  6325. std::make_pair("ConstantDataPointerPushConstant %int_0 %int_0 %data",
  6326. 5),
  6327. std::make_pair(
  6328. "ProgramScopeVariablePointerPushConstant %int_0 %int_0 %data", 5),
  6329. std::make_pair("PrintfInfo %int_0 %data", 5),
  6330. std::make_pair("PrintfBufferStorageBuffer %int_0 %int_0 %int_0", 5),
  6331. std::make_pair("PrintfBufferPointerPushConstant %int_0 %int_0 %int_0",
  6332. 5)}));
  6333. TEST_P(VersionCheck, V1) {
  6334. const std::string ext_inst = std::get<0>(GetParam());
  6335. const uint32_t version = std::get<1>(GetParam());
  6336. const std::string text = R"(
  6337. OpCapability Shader
  6338. OpExtension "SPV_KHR_non_semantic_info"
  6339. %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
  6340. OpMemoryModel Logical GLSL450
  6341. OpEntryPoint GLCompute %foo "foo"
  6342. OpExecutionMode %foo LocalSize 1 1 1
  6343. %foo_name = OpString "foo"
  6344. %data = OpString "1234"
  6345. %void = OpTypeVoid
  6346. %int = OpTypeInt 32 0
  6347. %int_0 = OpConstant %int 0
  6348. %int_1 = OpConstant %int 1
  6349. %int_4 = OpConstant %int 4
  6350. %null = OpConstantNull %int
  6351. %float = OpTypeFloat 32
  6352. %float_0 = OpConstant %float 0
  6353. %void_fn = OpTypeFunction %void
  6354. %foo = OpFunction %void None %void_fn
  6355. %entry = OpLabel
  6356. OpReturn
  6357. OpFunctionEnd
  6358. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  6359. %inst = OpExtInst %void %ext )" +
  6360. ext_inst;
  6361. CompileSuccessfully(text);
  6362. if (version <= 1) {
  6363. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6364. } else {
  6365. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6366. EXPECT_THAT(getDiagnosticString(),
  6367. HasSubstr("requires version " + std::to_string(version) +
  6368. ", but parsed version is 1"));
  6369. }
  6370. }
  6371. TEST_P(VersionCheck, V2) {
  6372. const std::string ext_inst = std::get<0>(GetParam());
  6373. const uint32_t version = std::get<1>(GetParam());
  6374. const std::string text = R"(
  6375. OpCapability Shader
  6376. OpExtension "SPV_KHR_non_semantic_info"
  6377. %ext = OpExtInstImport "NonSemantic.ClspvReflection.2"
  6378. OpMemoryModel Logical GLSL450
  6379. OpEntryPoint GLCompute %foo "foo"
  6380. OpExecutionMode %foo LocalSize 1 1 1
  6381. %foo_name = OpString "foo"
  6382. %data = OpString "1234"
  6383. %void = OpTypeVoid
  6384. %int = OpTypeInt 32 0
  6385. %int_0 = OpConstant %int 0
  6386. %int_1 = OpConstant %int 1
  6387. %int_4 = OpConstant %int 4
  6388. %null = OpConstantNull %int
  6389. %float = OpTypeFloat 32
  6390. %float_0 = OpConstant %float 0
  6391. %void_fn = OpTypeFunction %void
  6392. %foo = OpFunction %void None %void_fn
  6393. %entry = OpLabel
  6394. OpReturn
  6395. OpFunctionEnd
  6396. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  6397. %inst = OpExtInst %void %ext )" +
  6398. ext_inst;
  6399. CompileSuccessfully(text);
  6400. if (version <= 2) {
  6401. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6402. } else {
  6403. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6404. EXPECT_THAT(getDiagnosticString(),
  6405. HasSubstr("requires version " + std::to_string(version) +
  6406. ", but parsed version is 2"));
  6407. }
  6408. }
  6409. TEST_P(VersionCheck, V3) {
  6410. const std::string ext_inst = std::get<0>(GetParam());
  6411. const uint32_t version = std::get<1>(GetParam());
  6412. const std::string text = R"(
  6413. OpCapability Shader
  6414. OpExtension "SPV_KHR_non_semantic_info"
  6415. %ext = OpExtInstImport "NonSemantic.ClspvReflection.3"
  6416. OpMemoryModel Logical GLSL450
  6417. OpEntryPoint GLCompute %foo "foo"
  6418. OpExecutionMode %foo LocalSize 1 1 1
  6419. %foo_name = OpString "foo"
  6420. %data = OpString "1234"
  6421. %void = OpTypeVoid
  6422. %int = OpTypeInt 32 0
  6423. %int_0 = OpConstant %int 0
  6424. %int_1 = OpConstant %int 1
  6425. %int_4 = OpConstant %int 4
  6426. %null = OpConstantNull %int
  6427. %float = OpTypeFloat 32
  6428. %float_0 = OpConstant %float 0
  6429. %void_fn = OpTypeFunction %void
  6430. %foo = OpFunction %void None %void_fn
  6431. %entry = OpLabel
  6432. OpReturn
  6433. OpFunctionEnd
  6434. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  6435. %inst = OpExtInst %void %ext )" +
  6436. ext_inst;
  6437. CompileSuccessfully(text);
  6438. if (version <= 3) {
  6439. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6440. } else {
  6441. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6442. EXPECT_THAT(getDiagnosticString(),
  6443. HasSubstr("requires version " + std::to_string(version) +
  6444. ", but parsed version is 3"));
  6445. }
  6446. }
  6447. TEST_P(VersionCheck, V4) {
  6448. const std::string ext_inst = std::get<0>(GetParam());
  6449. const uint32_t version = std::get<1>(GetParam());
  6450. const std::string text = R"(
  6451. OpCapability Shader
  6452. OpExtension "SPV_KHR_non_semantic_info"
  6453. %ext = OpExtInstImport "NonSemantic.ClspvReflection.4"
  6454. OpMemoryModel Logical GLSL450
  6455. OpEntryPoint GLCompute %foo "foo"
  6456. OpExecutionMode %foo LocalSize 1 1 1
  6457. %foo_name = OpString "foo"
  6458. %data = OpString "1234"
  6459. %void = OpTypeVoid
  6460. %int = OpTypeInt 32 0
  6461. %int_0 = OpConstant %int 0
  6462. %int_1 = OpConstant %int 1
  6463. %int_4 = OpConstant %int 4
  6464. %null = OpConstantNull %int
  6465. %float = OpTypeFloat 32
  6466. %float_0 = OpConstant %float 0
  6467. %void_fn = OpTypeFunction %void
  6468. %foo = OpFunction %void None %void_fn
  6469. %entry = OpLabel
  6470. OpReturn
  6471. OpFunctionEnd
  6472. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  6473. %inst = OpExtInst %void %ext )" +
  6474. ext_inst;
  6475. CompileSuccessfully(text);
  6476. if (version <= 4) {
  6477. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6478. } else {
  6479. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6480. EXPECT_THAT(getDiagnosticString(),
  6481. HasSubstr("requires version " + std::to_string(version) +
  6482. ", but parsed version is 4"));
  6483. }
  6484. }
  6485. TEST_P(VersionCheck, V5) {
  6486. const std::string ext_inst = std::get<0>(GetParam());
  6487. const uint32_t version = std::get<1>(GetParam());
  6488. const std::string text = R"(
  6489. OpCapability Shader
  6490. OpExtension "SPV_KHR_non_semantic_info"
  6491. %ext = OpExtInstImport "NonSemantic.ClspvReflection.5"
  6492. OpMemoryModel Logical GLSL450
  6493. OpEntryPoint GLCompute %foo "foo"
  6494. OpExecutionMode %foo LocalSize 1 1 1
  6495. %foo_name = OpString "foo"
  6496. %data = OpString "1234"
  6497. %void = OpTypeVoid
  6498. %int = OpTypeInt 32 0
  6499. %int_0 = OpConstant %int 0
  6500. %int_1 = OpConstant %int 1
  6501. %int_4 = OpConstant %int 4
  6502. %null = OpConstantNull %int
  6503. %float = OpTypeFloat 32
  6504. %float_0 = OpConstant %float 0
  6505. %void_fn = OpTypeFunction %void
  6506. %foo = OpFunction %void None %void_fn
  6507. %entry = OpLabel
  6508. OpReturn
  6509. OpFunctionEnd
  6510. %decl = OpExtInst %void %ext Kernel %foo %foo_name
  6511. %inst = OpExtInst %void %ext )" +
  6512. ext_inst;
  6513. CompileSuccessfully(text);
  6514. if (version <= 5) {
  6515. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  6516. } else {
  6517. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  6518. EXPECT_THAT(getDiagnosticString(),
  6519. HasSubstr("requires version " + std::to_string(version) +
  6520. ", but parsed version is 1"));
  6521. }
  6522. }
  6523. TEST_F(ValidateExtInst, OpExtInstWithForwardNotAllowedSemantic) {
  6524. const std::string body = R"(
  6525. OpCapability Shader
  6526. OpExtension "SPV_KHR_non_semantic_info"
  6527. OpExtension "SPV_KHR_relaxed_extended_instruction"
  6528. %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
  6529. %extinst = OpExtInstImport "GLSL.std.450"
  6530. OpMemoryModel Logical GLSL450
  6531. OpEntryPoint GLCompute %2 "main"
  6532. OpExecutionMode %2 LocalSize 1 1 1
  6533. %3 = OpString "sample"
  6534. %void = OpTypeVoid
  6535. %uint = OpTypeInt 32 0
  6536. %f32 = OpTypeFloat 32
  6537. %uint_0 = OpConstant %uint 0
  6538. %f32_0 = OpConstant %f32 0
  6539. %f32_1 = OpConstant %f32 1
  6540. %7 = OpTypeFunction %void
  6541. %8 = OpExtInst %void %1 DebugSource %3 %3
  6542. %9 = OpExtInst %void %1 DebugCompilationUnit %uint_0 %uint_0 %8 %uint_0
  6543. %10 = OpExtInstWithForwardRefsKHR %void %1 DebugTypeFunction %uint_0 %11
  6544. %12 = OpExtInstWithForwardRefsKHR %void %1 DebugFunction %3 %10 %8 %uint_0 %uint_0 %11 %3 %uint_0 %uint_0
  6545. %11 = OpExtInst %void %1 DebugTypeComposite %3 %uint_0 %8 %uint_0 %uint_0 %9 %3 %uint_0 %uint_0 %12
  6546. %2 = OpFunction %void None %7
  6547. %13 = OpLabel
  6548. %18 = OpExtInstWithForwardRefsKHR %f32 %extinst FMin %f32_0 %19
  6549. %19 = OpExtInst %f32 %extinst FMin %f32_0 %f32_1
  6550. OpReturn
  6551. OpFunctionEnd
  6552. )";
  6553. CompileSuccessfully(body);
  6554. ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  6555. EXPECT_THAT(
  6556. getDiagnosticString(),
  6557. HasSubstr(
  6558. "OpExtInstWithForwardRefsKHR is only allowed with non-semantic "
  6559. "instructions.\n"
  6560. " %18 = OpExtInstWithForwardRefsKHR %float %2 FMin %float_0 %19\n"));
  6561. }
  6562. TEST_F(ValidateExtInst, OpExtInstRequiresNonSemanticBefore16) {
  6563. const std::string body = R"(
  6564. OpCapability Shader
  6565. OpExtension "SPV_KHR_non_semantic_info"
  6566. %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
  6567. %extinst = OpExtInstImport "GLSL.std.450"
  6568. OpMemoryModel Logical GLSL450
  6569. OpEntryPoint GLCompute %2 "main"
  6570. OpExecutionMode %2 LocalSize 1 1 1
  6571. %3 = OpString "sample"
  6572. %void = OpTypeVoid
  6573. %uint = OpTypeInt 32 0
  6574. %uint_0 = OpConstant %uint 0
  6575. %7 = OpTypeFunction %void
  6576. %8 = OpExtInst %void %1 DebugSource %3 %3
  6577. %9 = OpExtInst %void %1 DebugCompilationUnit %uint_0 %uint_0 %8 %uint_0
  6578. %10 = OpExtInstWithForwardRefsKHR %void %1 DebugTypeFunction %uint_0 %11
  6579. %12 = OpExtInstWithForwardRefsKHR %void %1 DebugFunction %3 %10 %8 %uint_0 %uint_0 %11 %3 %uint_0 %uint_0
  6580. %11 = OpExtInst %void %1 DebugTypeComposite %3 %uint_0 %8 %uint_0 %uint_0 %9 %3 %uint_0 %uint_0 %12
  6581. %2 = OpFunction %void None %7
  6582. %13 = OpLabel
  6583. OpReturn
  6584. OpFunctionEnd
  6585. )";
  6586. CompileSuccessfully(body);
  6587. ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
  6588. EXPECT_THAT(
  6589. getDiagnosticString(),
  6590. HasSubstr("ExtInstWithForwardRefsKHR requires one of the following "
  6591. "extensions: SPV_KHR_relaxed_extended_instruction \n"
  6592. " %11 = OpExtInstWithForwardRefsKHR %void %1 "
  6593. "DebugTypeFunction %uint_0 %12\n"));
  6594. }
  6595. } // namespace
  6596. } // namespace val
  6597. } // namespace spvtools