12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505 |
- #include "InstCombineInternal.h"
- #include "llvm-c/Initialization.h"
- #include "llvm-c/Transforms/InstCombine.h"
- #include "llvm/ADT/APInt.h"
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/ADT/None.h"
- #include "llvm/ADT/SmallPtrSet.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/ADT/Statistic.h"
- #include "llvm/ADT/TinyPtrVector.h"
- #include "llvm/Analysis/AliasAnalysis.h"
- #include "llvm/Analysis/AssumptionCache.h"
- #include "llvm/Analysis/BasicAliasAnalysis.h"
- #include "llvm/Analysis/BlockFrequencyInfo.h"
- #include "llvm/Analysis/CFG.h"
- #include "llvm/Analysis/ConstantFolding.h"
- #include "llvm/Analysis/EHPersonalities.h"
- #include "llvm/Analysis/GlobalsModRef.h"
- #include "llvm/Analysis/InstructionSimplify.h"
- #include "llvm/Analysis/LazyBlockFrequencyInfo.h"
- #include "llvm/Analysis/LoopInfo.h"
- #include "llvm/Analysis/MemoryBuiltins.h"
- #include "llvm/Analysis/OptimizationRemarkEmitter.h"
- #include "llvm/Analysis/ProfileSummaryInfo.h"
- #include "llvm/Analysis/TargetFolder.h"
- #include "llvm/Analysis/TargetLibraryInfo.h"
- #include "llvm/Analysis/TargetTransformInfo.h"
- #include "llvm/Analysis/ValueTracking.h"
- #include "llvm/Analysis/VectorUtils.h"
- #include "llvm/IR/BasicBlock.h"
- #include "llvm/IR/CFG.h"
- #include "llvm/IR/Constant.h"
- #include "llvm/IR/Constants.h"
- #include "llvm/IR/DIBuilder.h"
- #include "llvm/IR/DataLayout.h"
- #include "llvm/IR/DebugInfo.h"
- #include "llvm/IR/DerivedTypes.h"
- #include "llvm/IR/Dominators.h"
- #include "llvm/IR/Function.h"
- #include "llvm/IR/GetElementPtrTypeIterator.h"
- #include "llvm/IR/IRBuilder.h"
- #include "llvm/IR/InstrTypes.h"
- #include "llvm/IR/Instruction.h"
- #include "llvm/IR/Instructions.h"
- #include "llvm/IR/IntrinsicInst.h"
- #include "llvm/IR/Intrinsics.h"
- #include "llvm/IR/LegacyPassManager.h"
- #include "llvm/IR/Metadata.h"
- #include "llvm/IR/Operator.h"
- #include "llvm/IR/PassManager.h"
- #include "llvm/IR/PatternMatch.h"
- #include "llvm/IR/Type.h"
- #include "llvm/IR/Use.h"
- #include "llvm/IR/User.h"
- #include "llvm/IR/Value.h"
- #include "llvm/IR/ValueHandle.h"
- #include "llvm/InitializePasses.h"
- #include "llvm/Pass.h"
- #include "llvm/Support/CBindingWrapping.h"
- #include "llvm/Support/Casting.h"
- #include "llvm/Support/CommandLine.h"
- #include "llvm/Support/Compiler.h"
- #include "llvm/Support/Debug.h"
- #include "llvm/Support/DebugCounter.h"
- #include "llvm/Support/ErrorHandling.h"
- #include "llvm/Support/KnownBits.h"
- #include "llvm/Support/raw_ostream.h"
- #include "llvm/Transforms/InstCombine/InstCombine.h"
- #include "llvm/Transforms/Utils/Local.h"
- #include <algorithm>
- #include <cassert>
- #include <cstdint>
- #include <memory>
- #include <string>
- #include <utility>
- #define DEBUG_TYPE "instcombine"
- #include "llvm/Transforms/Utils/InstructionWorklist.h"
- using namespace llvm;
- using namespace llvm::PatternMatch;
- STATISTIC(NumWorklistIterations,
- "Number of instruction combining iterations performed");
- STATISTIC(NumCombined , "Number of insts combined");
- STATISTIC(NumConstProp, "Number of constant folds");
- STATISTIC(NumDeadInst , "Number of dead inst eliminated");
- STATISTIC(NumSunkInst , "Number of instructions sunk");
- STATISTIC(NumExpand, "Number of expansions");
- STATISTIC(NumFactor , "Number of factorizations");
- STATISTIC(NumReassoc , "Number of reassociations");
- DEBUG_COUNTER(VisitCounter, "instcombine-visit",
- "Controls which instructions are visited");
- static constexpr unsigned InstCombineDefaultMaxIterations = 1000;
- #ifndef NDEBUG
- static constexpr unsigned InstCombineDefaultInfiniteLoopThreshold = 100;
- #else
- static constexpr unsigned InstCombineDefaultInfiniteLoopThreshold = 1000;
- #endif
- static cl::opt<bool>
- EnableCodeSinking("instcombine-code-sinking", cl::desc("Enable code sinking"),
- cl::init(true));
- static cl::opt<unsigned> LimitMaxIterations(
- "instcombine-max-iterations",
- cl::desc("Limit the maximum number of instruction combining iterations"),
- cl::init(InstCombineDefaultMaxIterations));
- static cl::opt<unsigned> InfiniteLoopDetectionThreshold(
- "instcombine-infinite-loop-threshold",
- cl::desc("Number of instruction combining iterations considered an "
- "infinite loop"),
- cl::init(InstCombineDefaultInfiniteLoopThreshold), cl::Hidden);
- static cl::opt<unsigned>
- MaxArraySize("instcombine-maxarray-size", cl::init(1024),
- cl::desc("Maximum array size considered when doing a combine"));
- static cl::opt<unsigned> ShouldLowerDbgDeclare("instcombine-lower-dbg-declare",
- cl::Hidden, cl::init(true));
- Optional<Instruction *>
- InstCombiner::targetInstCombineIntrinsic(IntrinsicInst &II) {
-
- if (II.getCalledFunction()->isTargetIntrinsic()) {
- return TTI.instCombineIntrinsic(*this, II);
- }
- return None;
- }
- Optional<Value *> InstCombiner::targetSimplifyDemandedUseBitsIntrinsic(
- IntrinsicInst &II, APInt DemandedMask, KnownBits &Known,
- bool &KnownBitsComputed) {
-
- if (II.getCalledFunction()->isTargetIntrinsic()) {
- return TTI.simplifyDemandedUseBitsIntrinsic(*this, II, DemandedMask, Known,
- KnownBitsComputed);
- }
- return None;
- }
- Optional<Value *> InstCombiner::targetSimplifyDemandedVectorEltsIntrinsic(
- IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts, APInt &UndefElts2,
- APInt &UndefElts3,
- std::function<void(Instruction *, unsigned, APInt, APInt &)>
- SimplifyAndSetOp) {
-
- if (II.getCalledFunction()->isTargetIntrinsic()) {
- return TTI.simplifyDemandedVectorEltsIntrinsic(
- *this, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
- SimplifyAndSetOp);
- }
- return None;
- }
- Value *InstCombinerImpl::EmitGEPOffset(User *GEP) {
- return llvm::EmitGEPOffset(&Builder, DL, GEP);
- }
- bool InstCombinerImpl::isDesirableIntType(unsigned BitWidth) const {
- switch (BitWidth) {
- case 8:
- case 16:
- case 32:
- return true;
- default:
- return DL.isLegalInteger(BitWidth);
- }
- }
- bool InstCombinerImpl::shouldChangeType(unsigned FromWidth,
- unsigned ToWidth) const {
- bool FromLegal = FromWidth == 1 || DL.isLegalInteger(FromWidth);
- bool ToLegal = ToWidth == 1 || DL.isLegalInteger(ToWidth);
-
-
- if (ToWidth < FromWidth && isDesirableIntType(ToWidth))
- return true;
-
-
- if (FromLegal && !ToLegal)
- return false;
-
-
- if (!FromLegal && !ToLegal && ToWidth > FromWidth)
- return false;
- return true;
- }
- bool InstCombinerImpl::shouldChangeType(Type *From, Type *To) const {
-
-
- if (!From->isIntegerTy() || !To->isIntegerTy())
- return false;
- unsigned FromWidth = From->getPrimitiveSizeInBits();
- unsigned ToWidth = To->getPrimitiveSizeInBits();
- return shouldChangeType(FromWidth, ToWidth);
- }
- static bool maintainNoSignedWrap(BinaryOperator &I, Value *B, Value *C) {
- auto *OBO = dyn_cast<OverflowingBinaryOperator>(&I);
- if (!OBO || !OBO->hasNoSignedWrap())
- return false;
-
- Instruction::BinaryOps Opcode = I.getOpcode();
- if (Opcode != Instruction::Add && Opcode != Instruction::Sub)
- return false;
- const APInt *BVal, *CVal;
- if (!match(B, m_APInt(BVal)) || !match(C, m_APInt(CVal)))
- return false;
- bool Overflow = false;
- if (Opcode == Instruction::Add)
- (void)BVal->sadd_ov(*CVal, Overflow);
- else
- (void)BVal->ssub_ov(*CVal, Overflow);
- return !Overflow;
- }
- static bool hasNoUnsignedWrap(BinaryOperator &I) {
- auto *OBO = dyn_cast<OverflowingBinaryOperator>(&I);
- return OBO && OBO->hasNoUnsignedWrap();
- }
- static bool hasNoSignedWrap(BinaryOperator &I) {
- auto *OBO = dyn_cast<OverflowingBinaryOperator>(&I);
- return OBO && OBO->hasNoSignedWrap();
- }
- static void ClearSubclassDataAfterReassociation(BinaryOperator &I) {
- FPMathOperator *FPMO = dyn_cast<FPMathOperator>(&I);
- if (!FPMO) {
- I.clearSubclassOptionalData();
- return;
- }
- FastMathFlags FMF = I.getFastMathFlags();
- I.clearSubclassOptionalData();
- I.setFastMathFlags(FMF);
- }
- static bool simplifyAssocCastAssoc(BinaryOperator *BinOp1,
- InstCombinerImpl &IC) {
- auto *Cast = dyn_cast<CastInst>(BinOp1->getOperand(0));
- if (!Cast || !Cast->hasOneUse())
- return false;
-
- auto CastOpcode = Cast->getOpcode();
- if (CastOpcode != Instruction::ZExt)
- return false;
-
- if (!BinOp1->isBitwiseLogicOp())
- return false;
- auto AssocOpcode = BinOp1->getOpcode();
- auto *BinOp2 = dyn_cast<BinaryOperator>(Cast->getOperand(0));
- if (!BinOp2 || !BinOp2->hasOneUse() || BinOp2->getOpcode() != AssocOpcode)
- return false;
- Constant *C1, *C2;
- if (!match(BinOp1->getOperand(1), m_Constant(C1)) ||
- !match(BinOp2->getOperand(1), m_Constant(C2)))
- return false;
-
-
-
-
-
- Type *DestTy = C1->getType();
- Constant *CastC2 = ConstantExpr::getCast(CastOpcode, C2, DestTy);
- Constant *FoldedC = ConstantExpr::get(AssocOpcode, C1, CastC2);
- IC.replaceOperand(*Cast, 0, BinOp2->getOperand(0));
- IC.replaceOperand(*BinOp1, 1, FoldedC);
- return true;
- }
- Value *InstCombinerImpl::simplifyIntToPtrRoundTripCast(Value *Val) {
- auto *IntToPtr = dyn_cast<IntToPtrInst>(Val);
- if (IntToPtr && DL.getPointerTypeSizeInBits(IntToPtr->getDestTy()) ==
- DL.getTypeSizeInBits(IntToPtr->getSrcTy())) {
- auto *PtrToInt = dyn_cast<PtrToIntInst>(IntToPtr->getOperand(0));
- Type *CastTy = IntToPtr->getDestTy();
- if (PtrToInt &&
- CastTy->getPointerAddressSpace() ==
- PtrToInt->getSrcTy()->getPointerAddressSpace() &&
- DL.getPointerTypeSizeInBits(PtrToInt->getSrcTy()) ==
- DL.getTypeSizeInBits(PtrToInt->getDestTy())) {
- return CastInst::CreateBitOrPointerCast(PtrToInt->getOperand(0), CastTy,
- "", PtrToInt);
- }
- }
- return nullptr;
- }
- bool InstCombinerImpl::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
- Instruction::BinaryOps Opcode = I.getOpcode();
- bool Changed = false;
- do {
-
-
-
- if (I.isCommutative() && getComplexity(I.getOperand(0)) <
- getComplexity(I.getOperand(1)))
- Changed = !I.swapOperands();
- BinaryOperator *Op0 = dyn_cast<BinaryOperator>(I.getOperand(0));
- BinaryOperator *Op1 = dyn_cast<BinaryOperator>(I.getOperand(1));
- if (I.isAssociative()) {
-
- if (Op0 && Op0->getOpcode() == Opcode) {
- Value *A = Op0->getOperand(0);
- Value *B = Op0->getOperand(1);
- Value *C = I.getOperand(1);
-
- if (Value *V = SimplifyBinOp(Opcode, B, C, SQ.getWithInstruction(&I))) {
-
- replaceOperand(I, 0, A);
- replaceOperand(I, 1, V);
- bool IsNUW = hasNoUnsignedWrap(I) && hasNoUnsignedWrap(*Op0);
- bool IsNSW = maintainNoSignedWrap(I, B, C) && hasNoSignedWrap(*Op0);
-
-
-
- ClearSubclassDataAfterReassociation(I);
-
-
- if (IsNUW)
- I.setHasNoUnsignedWrap(true);
- if (IsNSW)
- I.setHasNoSignedWrap(true);
- Changed = true;
- ++NumReassoc;
- continue;
- }
- }
-
- if (Op1 && Op1->getOpcode() == Opcode) {
- Value *A = I.getOperand(0);
- Value *B = Op1->getOperand(0);
- Value *C = Op1->getOperand(1);
-
- if (Value *V = SimplifyBinOp(Opcode, A, B, SQ.getWithInstruction(&I))) {
-
- replaceOperand(I, 0, V);
- replaceOperand(I, 1, C);
-
-
- ClearSubclassDataAfterReassociation(I);
- Changed = true;
- ++NumReassoc;
- continue;
- }
- }
- }
- if (I.isAssociative() && I.isCommutative()) {
- if (simplifyAssocCastAssoc(&I, *this)) {
- Changed = true;
- ++NumReassoc;
- continue;
- }
-
- if (Op0 && Op0->getOpcode() == Opcode) {
- Value *A = Op0->getOperand(0);
- Value *B = Op0->getOperand(1);
- Value *C = I.getOperand(1);
-
- if (Value *V = SimplifyBinOp(Opcode, C, A, SQ.getWithInstruction(&I))) {
-
- replaceOperand(I, 0, V);
- replaceOperand(I, 1, B);
-
-
- ClearSubclassDataAfterReassociation(I);
- Changed = true;
- ++NumReassoc;
- continue;
- }
- }
-
- if (Op1 && Op1->getOpcode() == Opcode) {
- Value *A = I.getOperand(0);
- Value *B = Op1->getOperand(0);
- Value *C = Op1->getOperand(1);
-
- if (Value *V = SimplifyBinOp(Opcode, C, A, SQ.getWithInstruction(&I))) {
-
- replaceOperand(I, 0, B);
- replaceOperand(I, 1, V);
-
-
- ClearSubclassDataAfterReassociation(I);
- Changed = true;
- ++NumReassoc;
- continue;
- }
- }
-
-
- Value *A, *B;
- Constant *C1, *C2;
- if (Op0 && Op1 &&
- Op0->getOpcode() == Opcode && Op1->getOpcode() == Opcode &&
- match(Op0, m_OneUse(m_BinOp(m_Value(A), m_Constant(C1)))) &&
- match(Op1, m_OneUse(m_BinOp(m_Value(B), m_Constant(C2))))) {
- bool IsNUW = hasNoUnsignedWrap(I) &&
- hasNoUnsignedWrap(*Op0) &&
- hasNoUnsignedWrap(*Op1);
- BinaryOperator *NewBO = (IsNUW && Opcode == Instruction::Add) ?
- BinaryOperator::CreateNUW(Opcode, A, B) :
- BinaryOperator::Create(Opcode, A, B);
- if (isa<FPMathOperator>(NewBO)) {
- FastMathFlags Flags = I.getFastMathFlags();
- Flags &= Op0->getFastMathFlags();
- Flags &= Op1->getFastMathFlags();
- NewBO->setFastMathFlags(Flags);
- }
- InsertNewInstWith(NewBO, I);
- NewBO->takeName(Op1);
- replaceOperand(I, 0, NewBO);
- replaceOperand(I, 1, ConstantExpr::get(Opcode, C1, C2));
-
-
- ClearSubclassDataAfterReassociation(I);
- if (IsNUW)
- I.setHasNoUnsignedWrap(true);
- Changed = true;
- continue;
- }
- }
-
- return Changed;
- } while (true);
- }
- static bool leftDistributesOverRight(Instruction::BinaryOps LOp,
- Instruction::BinaryOps ROp) {
-
-
- if (LOp == Instruction::And)
- return ROp == Instruction::Or || ROp == Instruction::Xor;
-
- if (LOp == Instruction::Or)
- return ROp == Instruction::And;
-
-
- if (LOp == Instruction::Mul)
- return ROp == Instruction::Add || ROp == Instruction::Sub;
- return false;
- }
- static bool rightDistributesOverLeft(Instruction::BinaryOps LOp,
- Instruction::BinaryOps ROp) {
- if (Instruction::isCommutative(ROp))
- return leftDistributesOverRight(ROp, LOp);
-
- return Instruction::isBitwiseLogicOp(LOp) && Instruction::isShift(ROp);
-
-
-
- }
- static Value *getIdentityValue(Instruction::BinaryOps Opcode, Value *V) {
- if (isa<Constant>(V))
- return nullptr;
- return ConstantExpr::getBinOpIdentity(Opcode, V->getType());
- }
- static Instruction::BinaryOps
- getBinOpsForFactorization(Instruction::BinaryOps TopOpcode, BinaryOperator *Op,
- Value *&LHS, Value *&RHS) {
- assert(Op && "Expected a binary operator");
- LHS = Op->getOperand(0);
- RHS = Op->getOperand(1);
- if (TopOpcode == Instruction::Add || TopOpcode == Instruction::Sub) {
- Constant *C;
- if (match(Op, m_Shl(m_Value(), m_Constant(C)))) {
-
- RHS = ConstantExpr::getShl(ConstantInt::get(Op->getType(), 1), C);
- return Instruction::Mul;
- }
-
- }
- return Op->getOpcode();
- }
- Value *InstCombinerImpl::tryFactorization(BinaryOperator &I,
- Instruction::BinaryOps InnerOpcode,
- Value *A, Value *B, Value *C,
- Value *D) {
- assert(A && B && C && D && "All values must be provided");
- Value *V = nullptr;
- Value *SimplifiedInst = nullptr;
- Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
- Instruction::BinaryOps TopLevelOpcode = I.getOpcode();
-
- bool InnerCommutative = Instruction::isCommutative(InnerOpcode);
-
- if (leftDistributesOverRight(InnerOpcode, TopLevelOpcode))
-
-
- if (A == C || (InnerCommutative && A == D)) {
- if (A != C)
- std::swap(C, D);
-
-
- V = SimplifyBinOp(TopLevelOpcode, B, D, SQ.getWithInstruction(&I));
-
-
- if (!V && LHS->hasOneUse() && RHS->hasOneUse())
- V = Builder.CreateBinOp(TopLevelOpcode, B, D, RHS->getName());
- if (V) {
- SimplifiedInst = Builder.CreateBinOp(InnerOpcode, A, V);
- }
- }
-
- if (!SimplifiedInst && rightDistributesOverLeft(TopLevelOpcode, InnerOpcode))
-
-
- if (B == D || (InnerCommutative && B == C)) {
- if (B != D)
- std::swap(C, D);
-
-
- V = SimplifyBinOp(TopLevelOpcode, A, C, SQ.getWithInstruction(&I));
-
-
- if (!V && LHS->hasOneUse() && RHS->hasOneUse())
- V = Builder.CreateBinOp(TopLevelOpcode, A, C, LHS->getName());
- if (V) {
- SimplifiedInst = Builder.CreateBinOp(InnerOpcode, V, B);
- }
- }
- if (SimplifiedInst) {
- ++NumFactor;
- SimplifiedInst->takeName(&I);
-
- if (BinaryOperator *BO = dyn_cast<BinaryOperator>(SimplifiedInst)) {
- if (isa<OverflowingBinaryOperator>(SimplifiedInst)) {
- bool HasNSW = false;
- bool HasNUW = false;
- if (isa<OverflowingBinaryOperator>(&I)) {
- HasNSW = I.hasNoSignedWrap();
- HasNUW = I.hasNoUnsignedWrap();
- }
- if (auto *LOBO = dyn_cast<OverflowingBinaryOperator>(LHS)) {
- HasNSW &= LOBO->hasNoSignedWrap();
- HasNUW &= LOBO->hasNoUnsignedWrap();
- }
- if (auto *ROBO = dyn_cast<OverflowingBinaryOperator>(RHS)) {
- HasNSW &= ROBO->hasNoSignedWrap();
- HasNUW &= ROBO->hasNoUnsignedWrap();
- }
- if (TopLevelOpcode == Instruction::Add &&
- InnerOpcode == Instruction::Mul) {
-
-
-
-
-
-
-
- const APInt *CInt;
- if (match(V, m_APInt(CInt))) {
- if (!CInt->isMinSignedValue())
- BO->setHasNoSignedWrap(HasNSW);
- }
-
- BO->setHasNoUnsignedWrap(HasNUW);
- }
- }
- }
- }
- return SimplifiedInst;
- }
- Value *InstCombinerImpl::SimplifyUsingDistributiveLaws(BinaryOperator &I) {
- Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
- BinaryOperator *Op0 = dyn_cast<BinaryOperator>(LHS);
- BinaryOperator *Op1 = dyn_cast<BinaryOperator>(RHS);
- Instruction::BinaryOps TopLevelOpcode = I.getOpcode();
- {
-
- Value *A, *B, *C, *D;
- Instruction::BinaryOps LHSOpcode, RHSOpcode;
- if (Op0)
- LHSOpcode = getBinOpsForFactorization(TopLevelOpcode, Op0, A, B);
- if (Op1)
- RHSOpcode = getBinOpsForFactorization(TopLevelOpcode, Op1, C, D);
-
-
- if (Op0 && Op1 && LHSOpcode == RHSOpcode)
- if (Value *V = tryFactorization(I, LHSOpcode, A, B, C, D))
- return V;
-
-
- if (Op0)
- if (Value *Ident = getIdentityValue(LHSOpcode, RHS))
- if (Value *V = tryFactorization(I, LHSOpcode, A, B, RHS, Ident))
- return V;
-
-
- if (Op1)
- if (Value *Ident = getIdentityValue(RHSOpcode, LHS))
- if (Value *V = tryFactorization(I, RHSOpcode, LHS, Ident, C, D))
- return V;
- }
-
- if (Op0 && rightDistributesOverLeft(Op0->getOpcode(), TopLevelOpcode)) {
-
-
- Value *A = Op0->getOperand(0), *B = Op0->getOperand(1), *C = RHS;
- Instruction::BinaryOps InnerOpcode = Op0->getOpcode();
-
- auto SQDistributive = SQ.getWithInstruction(&I).getWithoutUndef();
- Value *L = SimplifyBinOp(TopLevelOpcode, A, C, SQDistributive);
- Value *R = SimplifyBinOp(TopLevelOpcode, B, C, SQDistributive);
-
- if (L && R) {
-
- ++NumExpand;
- C = Builder.CreateBinOp(InnerOpcode, L, R);
- C->takeName(&I);
- return C;
- }
-
- if (L && L == ConstantExpr::getBinOpIdentity(InnerOpcode, L->getType())) {
-
- ++NumExpand;
- C = Builder.CreateBinOp(TopLevelOpcode, B, C);
- C->takeName(&I);
- return C;
- }
-
- if (R && R == ConstantExpr::getBinOpIdentity(InnerOpcode, R->getType())) {
-
- ++NumExpand;
- C = Builder.CreateBinOp(TopLevelOpcode, A, C);
- C->takeName(&I);
- return C;
- }
- }
- if (Op1 && leftDistributesOverRight(TopLevelOpcode, Op1->getOpcode())) {
-
-
- Value *A = LHS, *B = Op1->getOperand(0), *C = Op1->getOperand(1);
- Instruction::BinaryOps InnerOpcode = Op1->getOpcode();
-
- auto SQDistributive = SQ.getWithInstruction(&I).getWithoutUndef();
- Value *L = SimplifyBinOp(TopLevelOpcode, A, B, SQDistributive);
- Value *R = SimplifyBinOp(TopLevelOpcode, A, C, SQDistributive);
-
- if (L && R) {
-
- ++NumExpand;
- A = Builder.CreateBinOp(InnerOpcode, L, R);
- A->takeName(&I);
- return A;
- }
-
- if (L && L == ConstantExpr::getBinOpIdentity(InnerOpcode, L->getType())) {
-
- ++NumExpand;
- A = Builder.CreateBinOp(TopLevelOpcode, A, C);
- A->takeName(&I);
- return A;
- }
-
- if (R && R == ConstantExpr::getBinOpIdentity(InnerOpcode, R->getType())) {
-
- ++NumExpand;
- A = Builder.CreateBinOp(TopLevelOpcode, A, B);
- A->takeName(&I);
- return A;
- }
- }
- return SimplifySelectsFeedingBinaryOp(I, LHS, RHS);
- }
- Value *InstCombinerImpl::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
- Value *LHS,
- Value *RHS) {
- Value *A, *B, *C, *D, *E, *F;
- bool LHSIsSelect = match(LHS, m_Select(m_Value(A), m_Value(B), m_Value(C)));
- bool RHSIsSelect = match(RHS, m_Select(m_Value(D), m_Value(E), m_Value(F)));
- if (!LHSIsSelect && !RHSIsSelect)
- return nullptr;
- FastMathFlags FMF;
- BuilderTy::FastMathFlagGuard Guard(Builder);
- if (isa<FPMathOperator>(&I)) {
- FMF = I.getFastMathFlags();
- Builder.setFastMathFlags(FMF);
- }
- Instruction::BinaryOps Opcode = I.getOpcode();
- SimplifyQuery Q = SQ.getWithInstruction(&I);
- Value *Cond, *True = nullptr, *False = nullptr;
- if (LHSIsSelect && RHSIsSelect && A == D) {
-
- Cond = A;
- True = SimplifyBinOp(Opcode, B, E, FMF, Q);
- False = SimplifyBinOp(Opcode, C, F, FMF, Q);
- if (LHS->hasOneUse() && RHS->hasOneUse()) {
- if (False && !True)
- True = Builder.CreateBinOp(Opcode, B, E);
- else if (True && !False)
- False = Builder.CreateBinOp(Opcode, C, F);
- }
- } else if (LHSIsSelect && LHS->hasOneUse()) {
-
- Cond = A;
- True = SimplifyBinOp(Opcode, B, RHS, FMF, Q);
- False = SimplifyBinOp(Opcode, C, RHS, FMF, Q);
- } else if (RHSIsSelect && RHS->hasOneUse()) {
-
- Cond = D;
- True = SimplifyBinOp(Opcode, LHS, E, FMF, Q);
- False = SimplifyBinOp(Opcode, LHS, F, FMF, Q);
- }
- if (!True || !False)
- return nullptr;
- Value *SI = Builder.CreateSelect(Cond, True, False);
- SI->takeName(&I);
- return SI;
- }
- void InstCombinerImpl::freelyInvertAllUsersOf(Value *I) {
- for (User *U : I->users()) {
- switch (cast<Instruction>(U)->getOpcode()) {
- case Instruction::Select: {
- auto *SI = cast<SelectInst>(U);
- SI->swapValues();
- SI->swapProfMetadata();
- break;
- }
- case Instruction::Br:
- cast<BranchInst>(U)->swapSuccessors();
- break;
- case Instruction::Xor:
- replaceInstUsesWith(cast<Instruction>(*U), I);
- break;
- default:
- llvm_unreachable("Got unexpected user - out of sync with "
- "canFreelyInvertAllUsersOf() ?");
- }
- }
- }
- Value *InstCombinerImpl::dyn_castNegVal(Value *V) const {
- Value *NegV;
- if (match(V, m_Neg(m_Value(NegV))))
- return NegV;
-
- if (ConstantInt *C = dyn_cast<ConstantInt>(V))
- return ConstantExpr::getNeg(C);
- if (ConstantDataVector *C = dyn_cast<ConstantDataVector>(V))
- if (C->getType()->getElementType()->isIntegerTy())
- return ConstantExpr::getNeg(C);
- if (ConstantVector *CV = dyn_cast<ConstantVector>(V)) {
- for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) {
- Constant *Elt = CV->getAggregateElement(i);
- if (!Elt)
- return nullptr;
- if (isa<UndefValue>(Elt))
- continue;
- if (!isa<ConstantInt>(Elt))
- return nullptr;
- }
- return ConstantExpr::getNeg(CV);
- }
-
- if (auto *CV = dyn_cast<Constant>(V))
- if (CV->getType()->isVectorTy() &&
- CV->getType()->getScalarType()->isIntegerTy() && CV->getSplatValue())
- return ConstantExpr::getNeg(CV);
- return nullptr;
- }
- Instruction *InstCombinerImpl::foldBinopOfSextBoolToSelect(BinaryOperator &BO) {
-
-
-
- Value *BO0 = BO.getOperand(0);
- Value *BO1 = BO.getOperand(1);
- Value *X;
- Constant *C;
- if (!match(BO0, m_SExt(m_Value(X))) || !match(BO1, m_ImmConstant(C)) ||
- !X->getType()->isIntOrIntVectorTy(1))
- return nullptr;
-
- Constant *Ones = ConstantInt::getAllOnesValue(BO.getType());
- Constant *Zero = ConstantInt::getNullValue(BO.getType());
- Constant *TVal = ConstantExpr::get(BO.getOpcode(), Ones, C);
- Constant *FVal = ConstantExpr::get(BO.getOpcode(), Zero, C);
- return SelectInst::Create(X, TVal, FVal);
- }
- static Value *foldOperationIntoSelectOperand(Instruction &I, Value *SO,
- InstCombiner::BuilderTy &Builder) {
- if (auto *Cast = dyn_cast<CastInst>(&I))
- return Builder.CreateCast(Cast->getOpcode(), SO, I.getType());
- if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
- assert(canConstantFoldCallTo(II, cast<Function>(II->getCalledOperand())) &&
- "Expected constant-foldable intrinsic");
- Intrinsic::ID IID = II->getIntrinsicID();
- if (II->arg_size() == 1)
- return Builder.CreateUnaryIntrinsic(IID, SO);
-
-
-
-
- assert(II->arg_size() == 2 && "Expected binary intrinsic");
- assert(isa<Constant>(II->getArgOperand(1)) && "Expected constant operand");
- return Builder.CreateBinaryIntrinsic(IID, SO, II->getArgOperand(1));
- }
- assert(I.isBinaryOp() && "Unexpected opcode for select folding");
-
- bool ConstIsRHS = isa<Constant>(I.getOperand(1));
- Constant *ConstOperand = cast<Constant>(I.getOperand(ConstIsRHS));
- if (auto *SOC = dyn_cast<Constant>(SO)) {
- if (ConstIsRHS)
- return ConstantExpr::get(I.getOpcode(), SOC, ConstOperand);
- return ConstantExpr::get(I.getOpcode(), ConstOperand, SOC);
- }
- Value *Op0 = SO, *Op1 = ConstOperand;
- if (!ConstIsRHS)
- std::swap(Op0, Op1);
- Value *NewBO = Builder.CreateBinOp(cast<BinaryOperator>(&I)->getOpcode(), Op0,
- Op1, SO->getName() + ".op");
- if (auto *NewBOI = dyn_cast<Instruction>(NewBO))
- NewBOI->copyIRFlags(&I);
- return NewBO;
- }
- Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op,
- SelectInst *SI) {
-
- if (!SI->hasOneUse())
- return nullptr;
- Value *TV = SI->getTrueValue();
- Value *FV = SI->getFalseValue();
- if (!(isa<Constant>(TV) || isa<Constant>(FV)))
- return nullptr;
-
- if (SI->getType()->isIntOrIntVectorTy(1))
- return nullptr;
-
-
- if (auto *BC = dyn_cast<BitCastInst>(&Op)) {
- VectorType *DestTy = dyn_cast<VectorType>(BC->getDestTy());
- VectorType *SrcTy = dyn_cast<VectorType>(BC->getSrcTy());
-
- if ((SrcTy == nullptr) != (DestTy == nullptr))
- return nullptr;
-
- if (SrcTy && SrcTy->getElementCount() != DestTy->getElementCount())
- return nullptr;
- }
-
-
-
-
-
-
-
- if (auto *CI = dyn_cast<CmpInst>(SI->getCondition())) {
- if (CI->hasOneUse()) {
- Value *Op0 = CI->getOperand(0), *Op1 = CI->getOperand(1);
-
-
-
- auto areLooselyEqual = [](Value *A, Value *B) {
- if (A == B)
- return true;
-
- Constant *ConstA, *ConstB;
- if (!match(A, m_Constant(ConstA)) || !match(B, m_Constant(ConstB)))
- return false;
-
- if (!A->getType()->isIntOrIntVectorTy() || A->getType() != B->getType())
- return false;
-
- auto *Cmp = ConstantExpr::getCompare(ICmpInst::ICMP_EQ, ConstA, ConstB);
- const APInt *C;
- return match(Cmp, m_APIntAllowUndef(C)) && C->isOne();
- };
- if ((areLooselyEqual(TV, Op0) && areLooselyEqual(FV, Op1)) ||
- (areLooselyEqual(FV, Op0) && areLooselyEqual(TV, Op1)))
- return nullptr;
- }
- }
- Value *NewTV = foldOperationIntoSelectOperand(Op, TV, Builder);
- Value *NewFV = foldOperationIntoSelectOperand(Op, FV, Builder);
- return SelectInst::Create(SI->getCondition(), NewTV, NewFV, "", nullptr, SI);
- }
- static Value *foldOperationIntoPhiValue(BinaryOperator *I, Value *InV,
- InstCombiner::BuilderTy &Builder) {
- bool ConstIsRHS = isa<Constant>(I->getOperand(1));
- Constant *C = cast<Constant>(I->getOperand(ConstIsRHS));
- if (auto *InC = dyn_cast<Constant>(InV)) {
- if (ConstIsRHS)
- return ConstantExpr::get(I->getOpcode(), InC, C);
- return ConstantExpr::get(I->getOpcode(), C, InC);
- }
- Value *Op0 = InV, *Op1 = C;
- if (!ConstIsRHS)
- std::swap(Op0, Op1);
- Value *RI = Builder.CreateBinOp(I->getOpcode(), Op0, Op1, "phi.bo");
- auto *FPInst = dyn_cast<Instruction>(RI);
- if (FPInst && isa<FPMathOperator>(FPInst))
- FPInst->copyFastMathFlags(I);
- return RI;
- }
- Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
- unsigned NumPHIValues = PN->getNumIncomingValues();
- if (NumPHIValues == 0)
- return nullptr;
-
-
-
- if (!PN->hasOneUse()) {
-
- for (User *U : PN->users()) {
- Instruction *UI = cast<Instruction>(U);
- if (UI != &I && !I.isIdenticalTo(UI))
- return nullptr;
- }
-
- }
-
-
-
-
-
- BasicBlock *NonConstBB = nullptr;
- for (unsigned i = 0; i != NumPHIValues; ++i) {
- Value *InVal = PN->getIncomingValue(i);
-
-
- if (!isa<FreezeInst>(I) && match(InVal, m_ImmConstant()))
- continue;
- if (isa<FreezeInst>(I) && isGuaranteedNotToBeUndefOrPoison(InVal))
- continue;
- if (isa<PHINode>(InVal)) return nullptr;
- if (NonConstBB) return nullptr;
- NonConstBB = PN->getIncomingBlock(i);
-
-
- if (isa<InvokeInst>(InVal))
- if (cast<Instruction>(InVal)->getParent() == NonConstBB)
- return nullptr;
-
-
-
- if (isPotentiallyReachable(I.getParent(), NonConstBB, nullptr, &DT, LI))
- return nullptr;
- }
-
-
-
-
-
- if (NonConstBB != nullptr) {
- BranchInst *BI = dyn_cast<BranchInst>(NonConstBB->getTerminator());
- if (!BI || !BI->isUnconditional() || !DT.isReachableFromEntry(NonConstBB))
- return nullptr;
- }
-
- PHINode *NewPN = PHINode::Create(I.getType(), PN->getNumIncomingValues());
- InsertNewInstBefore(NewPN, *PN);
- NewPN->takeName(PN);
-
-
- if (NonConstBB)
- Builder.SetInsertPoint(NonConstBB->getTerminator());
-
- if (SelectInst *SI = dyn_cast<SelectInst>(&I)) {
-
-
- Value *TrueV = SI->getTrueValue();
- Value *FalseV = SI->getFalseValue();
- BasicBlock *PhiTransBB = PN->getParent();
- for (unsigned i = 0; i != NumPHIValues; ++i) {
- BasicBlock *ThisBB = PN->getIncomingBlock(i);
- Value *TrueVInPred = TrueV->DoPHITranslation(PhiTransBB, ThisBB);
- Value *FalseVInPred = FalseV->DoPHITranslation(PhiTransBB, ThisBB);
- Value *InV = nullptr;
-
-
- Constant *InC = dyn_cast<Constant>(PN->getIncomingValue(i));
-
-
-
-
- if (InC && isa<ConstantInt>(InC))
- InV = InC->isNullValue() ? FalseVInPred : TrueVInPred;
- else {
-
-
-
-
-
-
-
-
- Builder.SetInsertPoint(ThisBB->getTerminator());
- InV = Builder.CreateSelect(PN->getIncomingValue(i), TrueVInPred,
- FalseVInPred, "phi.sel");
- }
- NewPN->addIncoming(InV, ThisBB);
- }
- } else if (CmpInst *CI = dyn_cast<CmpInst>(&I)) {
- Constant *C = cast<Constant>(I.getOperand(1));
- for (unsigned i = 0; i != NumPHIValues; ++i) {
- Value *InV = nullptr;
- if (auto *InC = dyn_cast<Constant>(PN->getIncomingValue(i)))
- InV = ConstantExpr::getCompare(CI->getPredicate(), InC, C);
- else
- InV = Builder.CreateCmp(CI->getPredicate(), PN->getIncomingValue(i),
- C, "phi.cmp");
- NewPN->addIncoming(InV, PN->getIncomingBlock(i));
- }
- } else if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
- for (unsigned i = 0; i != NumPHIValues; ++i) {
- Value *InV = foldOperationIntoPhiValue(BO, PN->getIncomingValue(i),
- Builder);
- NewPN->addIncoming(InV, PN->getIncomingBlock(i));
- }
- } else if (isa<FreezeInst>(&I)) {
- for (unsigned i = 0; i != NumPHIValues; ++i) {
- Value *InV;
- if (NonConstBB == PN->getIncomingBlock(i))
- InV = Builder.CreateFreeze(PN->getIncomingValue(i), "phi.fr");
- else
- InV = PN->getIncomingValue(i);
- NewPN->addIncoming(InV, PN->getIncomingBlock(i));
- }
- } else {
- CastInst *CI = cast<CastInst>(&I);
- Type *RetTy = CI->getType();
- for (unsigned i = 0; i != NumPHIValues; ++i) {
- Value *InV;
- if (Constant *InC = dyn_cast<Constant>(PN->getIncomingValue(i)))
- InV = ConstantExpr::getCast(CI->getOpcode(), InC, RetTy);
- else
- InV = Builder.CreateCast(CI->getOpcode(), PN->getIncomingValue(i),
- I.getType(), "phi.cast");
- NewPN->addIncoming(InV, PN->getIncomingBlock(i));
- }
- }
- for (User *U : make_early_inc_range(PN->users())) {
- Instruction *User = cast<Instruction>(U);
- if (User == &I) continue;
- replaceInstUsesWith(*User, NewPN);
- eraseInstFromFunction(*User);
- }
- return replaceInstUsesWith(I, NewPN);
- }
- Instruction *InstCombinerImpl::foldBinopWithPhiOperands(BinaryOperator &BO) {
-
-
-
- auto *Phi0 = dyn_cast<PHINode>(BO.getOperand(0));
- auto *Phi1 = dyn_cast<PHINode>(BO.getOperand(1));
- if (!Phi0 || !Phi1 || !Phi0->hasOneUse() || !Phi1->hasOneUse() ||
- Phi0->getNumOperands() != 2 || Phi1->getNumOperands() != 2)
- return nullptr;
-
- if (BO.getParent() != Phi0->getParent() ||
- BO.getParent() != Phi1->getParent())
- return nullptr;
-
- BasicBlock *ConstBB, *OtherBB;
- Constant *C0, *C1;
- if (match(Phi0->getIncomingValue(0), m_ImmConstant(C0))) {
- ConstBB = Phi0->getIncomingBlock(0);
- OtherBB = Phi0->getIncomingBlock(1);
- } else if (match(Phi0->getIncomingValue(1), m_ImmConstant(C0))) {
- ConstBB = Phi0->getIncomingBlock(1);
- OtherBB = Phi0->getIncomingBlock(0);
- } else {
- return nullptr;
- }
- if (!match(Phi1->getIncomingValueForBlock(ConstBB), m_ImmConstant(C1)))
- return nullptr;
-
-
-
- auto *PredBlockBranch = dyn_cast<BranchInst>(OtherBB->getTerminator());
- if (!PredBlockBranch || PredBlockBranch->isConditional() ||
- !DT.isReachableFromEntry(OtherBB))
- return nullptr;
-
-
-
- for (auto BBIter = BO.getParent()->begin(); &*BBIter != &BO; ++BBIter)
- if (!isGuaranteedToTransferExecutionToSuccessor(&*BBIter))
- return nullptr;
-
-
- Builder.SetInsertPoint(PredBlockBranch);
- Value *NewBO = Builder.CreateBinOp(BO.getOpcode(),
- Phi0->getIncomingValueForBlock(OtherBB),
- Phi1->getIncomingValueForBlock(OtherBB));
- if (auto *NotFoldedNewBO = dyn_cast<BinaryOperator>(NewBO))
- NotFoldedNewBO->copyIRFlags(&BO);
-
- Constant *NewC = ConstantExpr::get(BO.getOpcode(), C0, C1);
-
- PHINode *NewPhi = PHINode::Create(BO.getType(), 2);
- NewPhi->addIncoming(NewBO, OtherBB);
- NewPhi->addIncoming(NewC, ConstBB);
- return NewPhi;
- }
- Instruction *InstCombinerImpl::foldBinOpIntoSelectOrPhi(BinaryOperator &I) {
- if (!isa<Constant>(I.getOperand(1)))
- return nullptr;
- if (auto *Sel = dyn_cast<SelectInst>(I.getOperand(0))) {
- if (Instruction *NewSel = FoldOpIntoSelect(I, Sel))
- return NewSel;
- } else if (auto *PN = dyn_cast<PHINode>(I.getOperand(0))) {
- if (Instruction *NewPhi = foldOpIntoPhi(I, PN))
- return NewPhi;
- }
- return nullptr;
- }
- static Type *findElementAtOffset(PointerType *PtrTy, int64_t IntOffset,
- SmallVectorImpl<Value *> &NewIndices,
- const DataLayout &DL) {
-
- Type *Ty = PtrTy->getNonOpaquePointerElementType();
- if (!Ty->isSized())
- return nullptr;
- APInt Offset(DL.getIndexTypeSizeInBits(PtrTy), IntOffset);
- SmallVector<APInt> Indices = DL.getGEPIndicesForOffset(Ty, Offset);
- if (!Offset.isZero())
- return nullptr;
- for (const APInt &Index : Indices)
- NewIndices.push_back(ConstantInt::get(PtrTy->getContext(), Index));
- return Ty;
- }
- static bool shouldMergeGEPs(GEPOperator &GEP, GEPOperator &Src) {
-
-
-
- if (GEP.hasAllZeroIndices() && !Src.hasAllZeroIndices() &&
- !Src.hasOneUse())
- return false;
- return true;
- }
- Value *InstCombinerImpl::Descale(Value *Val, APInt Scale, bool &NoSignedWrap) {
- assert(isa<IntegerType>(Val->getType()) && "Can only descale integers!");
- assert(cast<IntegerType>(Val->getType())->getBitWidth() ==
- Scale.getBitWidth() && "Scale not compatible with value!");
-
- if (match(Val, m_Zero()) || Scale == 1) {
- NoSignedWrap = true;
- return Val;
- }
-
- if (Scale.isMinValue())
- return nullptr;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Value *Op = Val;
-
-
-
- std::pair<Instruction *, unsigned> Parent;
-
-
- bool RequireNoSignedWrap = false;
-
- int32_t logScale = Scale.exactLogBase2();
- for (;; Op = Parent.first->getOperand(Parent.second)) {
- if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
-
- APInt Quotient(Scale), Remainder(Scale);
- APInt::sdivrem(CI->getValue(), Scale, Quotient, Remainder);
- if (!Remainder.isMinValue())
-
- return nullptr;
-
- Op = ConstantInt::get(CI->getType(), Quotient);
- NoSignedWrap = true;
- break;
- }
- if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op)) {
- if (BO->getOpcode() == Instruction::Mul) {
-
- NoSignedWrap = BO->hasNoSignedWrap();
- if (RequireNoSignedWrap && !NoSignedWrap)
- return nullptr;
-
-
-
- Value *LHS = BO->getOperand(0);
- Value *RHS = BO->getOperand(1);
- if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
-
- if (CI->getValue() == Scale) {
-
-
- Op = LHS;
- break;
- }
-
- if (!Op->hasOneUse())
- return nullptr;
- Parent = std::make_pair(BO, 1);
- continue;
- }
-
-
- if (!Op->hasOneUse())
- return nullptr;
- Parent = std::make_pair(BO, 0);
- continue;
- }
- if (logScale > 0 && BO->getOpcode() == Instruction::Shl &&
- isa<ConstantInt>(BO->getOperand(1))) {
-
- NoSignedWrap = BO->hasNoSignedWrap();
- if (RequireNoSignedWrap && !NoSignedWrap)
- return nullptr;
- Value *LHS = BO->getOperand(0);
- int32_t Amt = cast<ConstantInt>(BO->getOperand(1))->
- getLimitedValue(Scale.getBitWidth());
-
- if (Amt == logScale) {
-
-
- Op = LHS;
- break;
- }
- if (Amt < logScale || !Op->hasOneUse())
- return nullptr;
-
-
- Parent = std::make_pair(BO, 1);
- Op = ConstantInt::get(BO->getType(), Amt - logScale);
- break;
- }
- }
- if (!Op->hasOneUse())
- return nullptr;
- if (CastInst *Cast = dyn_cast<CastInst>(Op)) {
- if (Cast->getOpcode() == Instruction::SExt) {
-
- unsigned SmallSize = Cast->getSrcTy()->getPrimitiveSizeInBits();
- APInt SmallScale = Scale.trunc(SmallSize);
-
-
-
-
-
- if (SmallScale.sext(Scale.getBitWidth()) != Scale)
-
- return nullptr;
- assert(SmallScale.exactLogBase2() == logScale);
-
- RequireNoSignedWrap = true;
-
- Parent = std::make_pair(Cast, 0);
- Scale = SmallScale;
- continue;
- }
- if (Cast->getOpcode() == Instruction::Trunc) {
-
-
-
-
-
-
- if (RequireNoSignedWrap)
- return nullptr;
-
- unsigned LargeSize = Cast->getSrcTy()->getPrimitiveSizeInBits();
- Parent = std::make_pair(Cast, 0);
- Scale = Scale.sext(LargeSize);
- if (logScale + 1 == (int32_t)Cast->getType()->getPrimitiveSizeInBits())
- logScale = -1;
- assert(Scale.exactLogBase2() == logScale);
- continue;
- }
- }
-
- return nullptr;
- }
-
- if (match(Op, m_Zero())) {
- NoSignedWrap = true;
- return Op;
- }
-
-
-
-
- if (!Parent.first)
-
- return Op;
-
- assert(Parent.first->hasOneUse() && "Drilled down when more than one use!");
- assert(Op != Parent.first->getOperand(Parent.second) &&
- "Descaling was a no-op?");
- replaceOperand(*Parent.first, Parent.second, Op);
- Worklist.push(Parent.first);
-
-
-
-
-
-
- Instruction *Ancestor = Parent.first;
- do {
- if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Ancestor)) {
-
-
-
- bool OpNoSignedWrap = BO->hasNoSignedWrap();
- NoSignedWrap &= OpNoSignedWrap;
- if (NoSignedWrap != OpNoSignedWrap) {
- BO->setHasNoSignedWrap(NoSignedWrap);
- Worklist.push(Ancestor);
- }
- } else if (Ancestor->getOpcode() == Instruction::Trunc) {
-
-
-
- NoSignedWrap = false;
- }
- assert((Ancestor->getOpcode() != Instruction::SExt || NoSignedWrap) &&
- "Failed to keep proper track of nsw flags while drilling down?");
- if (Ancestor == Val)
-
- return Val;
-
- assert(Ancestor->hasOneUse() && "Drilled down when more than one use!");
- Ancestor = Ancestor->user_back();
- } while (true);
- }
- Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
- if (!isa<VectorType>(Inst.getType()))
- return nullptr;
- BinaryOperator::BinaryOps Opcode = Inst.getOpcode();
- Value *LHS = Inst.getOperand(0), *RHS = Inst.getOperand(1);
- assert(cast<VectorType>(LHS->getType())->getElementCount() ==
- cast<VectorType>(Inst.getType())->getElementCount());
- assert(cast<VectorType>(RHS->getType())->getElementCount() ==
- cast<VectorType>(Inst.getType())->getElementCount());
-
-
-
- Value *L0, *L1, *R0, *R1;
- ArrayRef<int> Mask;
- if (match(LHS, m_Shuffle(m_Value(L0), m_Value(L1), m_Mask(Mask))) &&
- match(RHS, m_Shuffle(m_Value(R0), m_Value(R1), m_SpecificMask(Mask))) &&
- LHS->hasOneUse() && RHS->hasOneUse() &&
- cast<ShuffleVectorInst>(LHS)->isConcat() &&
- cast<ShuffleVectorInst>(RHS)->isConcat()) {
-
-
-
-
-
- Value *NewBO0 = Builder.CreateBinOp(Opcode, L0, R0);
- if (auto *BO = dyn_cast<BinaryOperator>(NewBO0))
- BO->copyIRFlags(&Inst);
- Value *NewBO1 = Builder.CreateBinOp(Opcode, L1, R1);
- if (auto *BO = dyn_cast<BinaryOperator>(NewBO1))
- BO->copyIRFlags(&Inst);
- return new ShuffleVectorInst(NewBO0, NewBO1, Mask);
- }
-
-
-
- if (!isSafeToSpeculativelyExecute(&Inst))
- return nullptr;
- auto createBinOpShuffle = [&](Value *X, Value *Y, ArrayRef<int> M) {
- Value *XY = Builder.CreateBinOp(Opcode, X, Y);
- if (auto *BO = dyn_cast<BinaryOperator>(XY))
- BO->copyIRFlags(&Inst);
- return new ShuffleVectorInst(XY, M);
- };
-
-
- Value *V1, *V2;
- if (match(LHS, m_Shuffle(m_Value(V1), m_Undef(), m_Mask(Mask))) &&
- match(RHS, m_Shuffle(m_Value(V2), m_Undef(), m_SpecificMask(Mask))) &&
- V1->getType() == V2->getType() &&
- (LHS->hasOneUse() || RHS->hasOneUse() || LHS == RHS)) {
-
- return createBinOpShuffle(V1, V2, Mask);
- }
-
-
- if (Inst.isCommutative() &&
- match(LHS, m_Shuffle(m_Value(V1), m_Value(V2), m_Mask(Mask))) &&
- match(RHS,
- m_Shuffle(m_Specific(V2), m_Specific(V1), m_SpecificMask(Mask)))) {
- auto *LShuf = cast<ShuffleVectorInst>(LHS);
- auto *RShuf = cast<ShuffleVectorInst>(RHS);
-
-
-
-
- if (LShuf->isSelect() &&
- !is_contained(LShuf->getShuffleMask(), UndefMaskElem) &&
- RShuf->isSelect() &&
- !is_contained(RShuf->getShuffleMask(), UndefMaskElem)) {
-
-
-
-
- Instruction *NewBO = BinaryOperator::Create(Opcode, V1, V2);
- NewBO->copyIRFlags(&Inst);
- return NewBO;
- }
- }
-
-
-
-
-
- Constant *C;
- auto *InstVTy = dyn_cast<FixedVectorType>(Inst.getType());
- if (InstVTy &&
- match(&Inst,
- m_c_BinOp(m_OneUse(m_Shuffle(m_Value(V1), m_Undef(), m_Mask(Mask))),
- m_ImmConstant(C))) &&
- cast<FixedVectorType>(V1->getType())->getNumElements() <=
- InstVTy->getNumElements()) {
- assert(InstVTy->getScalarType() == V1->getType()->getScalarType() &&
- "Shuffle should not change scalar type");
-
-
-
-
-
- bool ConstOp1 = isa<Constant>(RHS);
- ArrayRef<int> ShMask = Mask;
- unsigned SrcVecNumElts =
- cast<FixedVectorType>(V1->getType())->getNumElements();
- UndefValue *UndefScalar = UndefValue::get(C->getType()->getScalarType());
- SmallVector<Constant *, 16> NewVecC(SrcVecNumElts, UndefScalar);
- bool MayChange = true;
- unsigned NumElts = InstVTy->getNumElements();
- for (unsigned I = 0; I < NumElts; ++I) {
- Constant *CElt = C->getAggregateElement(I);
- if (ShMask[I] >= 0) {
- assert(ShMask[I] < (int)NumElts && "Not expecting narrowing shuffle");
- Constant *NewCElt = NewVecC[ShMask[I]];
-
-
-
-
-
-
- if (!CElt || (!isa<UndefValue>(NewCElt) && NewCElt != CElt) ||
- I >= SrcVecNumElts) {
- MayChange = false;
- break;
- }
- NewVecC[ShMask[I]] = CElt;
- }
-
-
-
-
-
-
-
-
-
- if (I >= SrcVecNumElts || ShMask[I] < 0) {
- Constant *MaybeUndef =
- ConstOp1 ? ConstantExpr::get(Opcode, UndefScalar, CElt)
- : ConstantExpr::get(Opcode, CElt, UndefScalar);
- if (!match(MaybeUndef, m_Undef())) {
- MayChange = false;
- break;
- }
- }
- }
- if (MayChange) {
- Constant *NewC = ConstantVector::get(NewVecC);
-
-
-
- if (Inst.isIntDivRem() || (Inst.isShift() && ConstOp1))
- NewC = getSafeVectorConstantForBinop(Opcode, NewC, ConstOp1);
-
-
- Value *NewLHS = ConstOp1 ? V1 : NewC;
- Value *NewRHS = ConstOp1 ? NewC : V1;
- return createBinOpShuffle(NewLHS, NewRHS, Mask);
- }
- }
-
- if (Inst.isAssociative() && Inst.isCommutative()) {
-
- if (isa<ShuffleVectorInst>(RHS))
- std::swap(LHS, RHS);
- Value *X;
- ArrayRef<int> MaskC;
- int SplatIndex;
- Value *Y, *OtherOp;
- if (!match(LHS,
- m_OneUse(m_Shuffle(m_Value(X), m_Undef(), m_Mask(MaskC)))) ||
- !match(MaskC, m_SplatOrUndefMask(SplatIndex)) ||
- X->getType() != Inst.getType() ||
- !match(RHS, m_OneUse(m_BinOp(Opcode, m_Value(Y), m_Value(OtherOp)))))
- return nullptr;
-
-
-
- if (isSplatValue(OtherOp, SplatIndex)) {
- std::swap(Y, OtherOp);
- } else if (!isSplatValue(Y, SplatIndex)) {
- return nullptr;
- }
-
-
-
- Value *NewBO = Builder.CreateBinOp(Opcode, X, Y);
- SmallVector<int, 8> NewMask(MaskC.size(), SplatIndex);
- Value *NewSplat = Builder.CreateShuffleVector(NewBO, NewMask);
- Instruction *R = BinaryOperator::Create(Opcode, NewSplat, OtherOp);
-
-
- if (isa<FPMathOperator>(R)) {
- R->copyFastMathFlags(&Inst);
- R->andIRFlags(RHS);
- }
- if (auto *NewInstBO = dyn_cast<BinaryOperator>(NewBO))
- NewInstBO->copyIRFlags(R);
- return R;
- }
- return nullptr;
- }
- Instruction *InstCombinerImpl::narrowMathIfNoOverflow(BinaryOperator &BO) {
-
- Value *Op0 = BO.getOperand(0), *Op1 = BO.getOperand(1);
-
-
- if (BO.getOpcode() == Instruction::Sub)
- std::swap(Op0, Op1);
- Value *X;
- bool IsSext = match(Op0, m_SExt(m_Value(X)));
- if (!IsSext && !match(Op0, m_ZExt(m_Value(X))))
- return nullptr;
-
-
- CastInst::CastOps CastOpc = IsSext ? Instruction::SExt : Instruction::ZExt;
- Value *Y;
- if (!(match(Op1, m_ZExtOrSExt(m_Value(Y))) && X->getType() == Y->getType() &&
- cast<Operator>(Op1)->getOpcode() == CastOpc &&
- (Op0->hasOneUse() || Op1->hasOneUse()))) {
-
-
- Constant *WideC;
- if (!Op0->hasOneUse() || !match(Op1, m_Constant(WideC)))
- return nullptr;
- Constant *NarrowC = ConstantExpr::getTrunc(WideC, X->getType());
- if (ConstantExpr::getCast(CastOpc, NarrowC, BO.getType()) != WideC)
- return nullptr;
- Y = NarrowC;
- }
-
- if (BO.getOpcode() == Instruction::Sub)
- std::swap(X, Y);
-
-
- if (!willNotOverflow(BO.getOpcode(), X, Y, BO, IsSext))
- return nullptr;
-
-
- Value *NarrowBO = Builder.CreateBinOp(BO.getOpcode(), X, Y, "narrow");
- if (auto *NewBinOp = dyn_cast<BinaryOperator>(NarrowBO)) {
- if (IsSext)
- NewBinOp->setHasNoSignedWrap();
- else
- NewBinOp->setHasNoUnsignedWrap();
- }
- return CastInst::Create(CastOpc, NarrowBO, BO.getType());
- }
- static bool isMergedGEPInBounds(GEPOperator &GEP1, GEPOperator &GEP2) {
-
- if (!GEP1.isInBounds() && !GEP2.isInBounds())
- return false;
- return (GEP1.isInBounds() || GEP1.hasAllZeroIndices()) &&
- (GEP2.isInBounds() || GEP2.hasAllZeroIndices());
- }
- static Instruction *foldSelectGEP(GetElementPtrInst &GEP,
- InstCombiner::BuilderTy &Builder) {
- if (!GEP.hasAllConstantIndices())
- return nullptr;
- Instruction *Sel;
- Value *Cond;
- Constant *TrueC, *FalseC;
- if (!match(GEP.getPointerOperand(), m_Instruction(Sel)) ||
- !match(Sel,
- m_Select(m_Value(Cond), m_Constant(TrueC), m_Constant(FalseC))))
- return nullptr;
-
-
-
- SmallVector<Value *, 4> IndexC(GEP.indices());
- bool IsInBounds = GEP.isInBounds();
- Type *Ty = GEP.getSourceElementType();
- Value *NewTrueC = IsInBounds ? Builder.CreateInBoundsGEP(Ty, TrueC, IndexC)
- : Builder.CreateGEP(Ty, TrueC, IndexC);
- Value *NewFalseC = IsInBounds ? Builder.CreateInBoundsGEP(Ty, FalseC, IndexC)
- : Builder.CreateGEP(Ty, FalseC, IndexC);
- return SelectInst::Create(Cond, NewTrueC, NewFalseC, "", nullptr, Sel);
- }
- Instruction *InstCombinerImpl::visitGEPOfGEP(GetElementPtrInst &GEP,
- GEPOperator *Src) {
-
-
-
- if (Src->getResultElementType() != GEP.getSourceElementType())
- return nullptr;
- if (!shouldMergeGEPs(*cast<GEPOperator>(&GEP), *Src))
- return nullptr;
- if (Src->getNumOperands() == 2 && GEP.getNumOperands() == 2 &&
- Src->hasOneUse()) {
- Value *GO1 = GEP.getOperand(1);
- Value *SO1 = Src->getOperand(1);
- if (LI) {
-
- if (Loop *L = LI->getLoopFor(GEP.getParent())) {
-
-
-
- if (L->isLoopInvariant(GO1) && !L->isLoopInvariant(SO1)) {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- auto *SO0 = Src->getOperand(0);
- auto *SO0Ty = SO0->getType();
- if (!isa<VectorType>(GEP.getType()) ||
- isa<VectorType>(SO0Ty)) {
- Src->setOperand(1, GO1);
- GEP.setOperand(1, SO1);
- return &GEP;
- } else {
-
-
-
- Builder.SetInsertPoint(cast<Instruction>(Src));
- Value *NewSrc = Builder.CreateGEP(
- GEP.getSourceElementType(), SO0, GO1, Src->getName());
-
- if (auto *NewSrcGEPI = dyn_cast<GetElementPtrInst>(NewSrc))
- NewSrcGEPI->setIsInBounds(Src->isInBounds());
- GetElementPtrInst *NewGEP = GetElementPtrInst::Create(
- GEP.getSourceElementType(), NewSrc, {SO1});
- NewGEP->setIsInBounds(GEP.isInBounds());
- return NewGEP;
- }
- }
- }
- }
- }
-
-
-
- if (auto *SrcGEP = dyn_cast<GEPOperator>(Src->getOperand(0)))
- if (SrcGEP->getNumOperands() == 2 && shouldMergeGEPs(*Src, *SrcGEP))
- return nullptr;
- SmallVector<Value*, 8> Indices;
-
- bool EndsWithSequential = false;
- for (gep_type_iterator I = gep_type_begin(*Src), E = gep_type_end(*Src);
- I != E; ++I)
- EndsWithSequential = I.isSequential();
-
- if (EndsWithSequential) {
-
-
- Value *SO1 = Src->getOperand(Src->getNumOperands()-1);
- Value *GO1 = GEP.getOperand(1);
-
-
-
-
- if (SO1->getType() != GO1->getType())
- return nullptr;
- Value *Sum =
- SimplifyAddInst(GO1, SO1, false, false, SQ.getWithInstruction(&GEP));
-
-
- if (Sum == nullptr)
- return nullptr;
-
- if (Src->getNumOperands() == 2) {
- GEP.setIsInBounds(isMergedGEPInBounds(*Src, *cast<GEPOperator>(&GEP)));
- replaceOperand(GEP, 0, Src->getOperand(0));
- replaceOperand(GEP, 1, Sum);
- return &GEP;
- }
- Indices.append(Src->op_begin()+1, Src->op_end()-1);
- Indices.push_back(Sum);
- Indices.append(GEP.op_begin()+2, GEP.op_end());
- } else if (isa<Constant>(*GEP.idx_begin()) &&
- cast<Constant>(*GEP.idx_begin())->isNullValue() &&
- Src->getNumOperands() != 1) {
-
- Indices.append(Src->op_begin()+1, Src->op_end());
- Indices.append(GEP.idx_begin()+1, GEP.idx_end());
- }
- if (!Indices.empty())
- return isMergedGEPInBounds(*Src, *cast<GEPOperator>(&GEP))
- ? GetElementPtrInst::CreateInBounds(
- Src->getSourceElementType(), Src->getOperand(0), Indices,
- GEP.getName())
- : GetElementPtrInst::Create(Src->getSourceElementType(),
- Src->getOperand(0), Indices,
- GEP.getName());
- return nullptr;
- }
- Instruction *InstCombinerImpl::visitGEPOfBitcast(BitCastInst *BCI,
- GetElementPtrInst &GEP) {
-
-
- PointerType *SrcType = cast<PointerType>(BCI->getSrcTy());
- if (SrcType->isOpaque())
- return nullptr;
- Type *GEPEltType = GEP.getSourceElementType();
- Type *SrcEltType = SrcType->getNonOpaquePointerElementType();
- Value *SrcOp = BCI->getOperand(0);
-
-
-
-
- auto areMatchingArrayAndVecTypes = [](Type *ArrTy, Type *VecTy,
- const DataLayout &DL) {
- auto *VecVTy = cast<FixedVectorType>(VecTy);
- return ArrTy->getArrayElementType() == VecVTy->getElementType() &&
- ArrTy->getArrayNumElements() == VecVTy->getNumElements() &&
- DL.getTypeAllocSize(ArrTy) == DL.getTypeAllocSize(VecTy);
- };
- if (GEP.getNumOperands() == 3 &&
- ((GEPEltType->isArrayTy() && isa<FixedVectorType>(SrcEltType) &&
- areMatchingArrayAndVecTypes(GEPEltType, SrcEltType, DL)) ||
- (isa<FixedVectorType>(GEPEltType) && SrcEltType->isArrayTy() &&
- areMatchingArrayAndVecTypes(SrcEltType, GEPEltType, DL)))) {
-
-
-
-
- SmallVector<Value *, 8> Indices(GEP.indices());
- Value *NGEP = GEP.isInBounds()
- ? Builder.CreateInBoundsGEP(SrcEltType, SrcOp, Indices)
- : Builder.CreateGEP(SrcEltType, SrcOp, Indices);
- NGEP->takeName(&GEP);
-
- if (NGEP->getType()->getPointerAddressSpace() != GEP.getAddressSpace())
- return new AddrSpaceCastInst(NGEP, GEP.getType());
- return replaceInstUsesWith(GEP, NGEP);
- }
-
-
-
-
-
- unsigned OffsetBits = DL.getIndexTypeSizeInBits(GEP.getType());
- APInt Offset(OffsetBits, 0);
-
-
-
-
-
-
- if (!isa<BitCastInst>(SrcOp) && GEP.accumulateConstantOffset(DL, Offset) &&
- !isAllocationFn(SrcOp, &TLI)) {
-
-
- if (!Offset) {
-
-
- if (isa<AllocaInst>(SrcOp)) {
-
- if (Instruction *I = visitBitCast(*BCI)) {
- if (I != BCI) {
- I->takeName(BCI);
- BCI->getParent()->getInstList().insert(BCI->getIterator(), I);
- replaceInstUsesWith(*BCI, I);
- }
- return &GEP;
- }
- }
- if (SrcType->getPointerAddressSpace() != GEP.getAddressSpace())
- return new AddrSpaceCastInst(SrcOp, GEP.getType());
- return new BitCastInst(SrcOp, GEP.getType());
- }
-
-
-
- SmallVector<Value*, 8> NewIndices;
- if (findElementAtOffset(SrcType, Offset.getSExtValue(), NewIndices, DL)) {
- Value *NGEP =
- GEP.isInBounds()
- ? Builder.CreateInBoundsGEP(SrcEltType, SrcOp, NewIndices)
- : Builder.CreateGEP(SrcEltType, SrcOp, NewIndices);
- if (NGEP->getType() == GEP.getType())
- return replaceInstUsesWith(GEP, NGEP);
- NGEP->takeName(&GEP);
- if (NGEP->getType()->getPointerAddressSpace() != GEP.getAddressSpace())
- return new AddrSpaceCastInst(NGEP, GEP.getType());
- return new BitCastInst(NGEP, GEP.getType());
- }
- }
- return nullptr;
- }
- Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
- Value *PtrOp = GEP.getOperand(0);
- SmallVector<Value *, 8> Indices(GEP.indices());
- Type *GEPType = GEP.getType();
- Type *GEPEltType = GEP.getSourceElementType();
- bool IsGEPSrcEleScalable = isa<ScalableVectorType>(GEPEltType);
- if (Value *V = SimplifyGEPInst(GEPEltType, PtrOp, Indices, GEP.isInBounds(),
- SQ.getWithInstruction(&GEP)))
- return replaceInstUsesWith(GEP, V);
-
-
-
- if (auto *GEPFVTy = dyn_cast<FixedVectorType>(GEPType)) {
- auto VWidth = GEPFVTy->getNumElements();
- APInt UndefElts(VWidth, 0);
- APInt AllOnesEltMask(APInt::getAllOnes(VWidth));
- if (Value *V = SimplifyDemandedVectorElts(&GEP, AllOnesEltMask,
- UndefElts)) {
- if (V != &GEP)
- return replaceInstUsesWith(GEP, V);
- return &GEP;
- }
-
-
-
- }
-
-
- bool MadeChange = false;
-
-
- Type *NewScalarIndexTy =
- DL.getIndexType(GEP.getPointerOperandType()->getScalarType());
- gep_type_iterator GTI = gep_type_begin(GEP);
- for (User::op_iterator I = GEP.op_begin() + 1, E = GEP.op_end(); I != E;
- ++I, ++GTI) {
-
- if (GTI.isStruct())
- continue;
- Type *IndexTy = (*I)->getType();
- Type *NewIndexType =
- IndexTy->isVectorTy()
- ? VectorType::get(NewScalarIndexTy,
- cast<VectorType>(IndexTy)->getElementCount())
- : NewScalarIndexTy;
-
-
- Type *EltTy = GTI.getIndexedType();
- if (EltTy->isSized() && DL.getTypeAllocSize(EltTy).isZero())
- if (!isa<Constant>(*I) || !match(I->get(), m_Zero())) {
- *I = Constant::getNullValue(NewIndexType);
- MadeChange = true;
- }
- if (IndexTy != NewIndexType) {
-
-
-
- *I = Builder.CreateIntCast(*I, NewIndexType, true);
- MadeChange = true;
- }
- }
- if (MadeChange)
- return &GEP;
-
- if (auto *PN = dyn_cast<PHINode>(PtrOp)) {
- auto *Op1 = dyn_cast<GetElementPtrInst>(PN->getOperand(0));
- if (!Op1)
- return nullptr;
-
-
-
-
-
-
- if (Op1 == &GEP)
- return nullptr;
- int DI = -1;
- for (auto I = PN->op_begin()+1, E = PN->op_end(); I !=E; ++I) {
- auto *Op2 = dyn_cast<GetElementPtrInst>(*I);
- if (!Op2 || Op1->getNumOperands() != Op2->getNumOperands())
- return nullptr;
-
- if (Op2 == &GEP)
- return nullptr;
-
- Type *CurTy = nullptr;
- for (unsigned J = 0, F = Op1->getNumOperands(); J != F; ++J) {
- if (Op1->getOperand(J)->getType() != Op2->getOperand(J)->getType())
- return nullptr;
- if (Op1->getOperand(J) != Op2->getOperand(J)) {
- if (DI == -1) {
-
-
-
-
-
- if (J > 1) {
- assert(CurTy && "No current type?");
- if (CurTy->isStructTy())
- return nullptr;
- }
- DI = J;
- } else {
-
-
-
-
-
-
- return nullptr;
- }
- }
-
- if (J > 0) {
- if (J == 1) {
- CurTy = Op1->getSourceElementType();
- } else {
- CurTy =
- GetElementPtrInst::getTypeAtIndex(CurTy, Op1->getOperand(J));
- }
- }
- }
- }
-
-
-
- if (DI != -1 && !PN->hasOneUse())
- return nullptr;
- auto *NewGEP = cast<GetElementPtrInst>(Op1->clone());
- if (DI == -1) {
-
-
- } else {
-
-
-
- PHINode *NewPN;
- {
- IRBuilderBase::InsertPointGuard Guard(Builder);
- Builder.SetInsertPoint(PN);
- NewPN = Builder.CreatePHI(Op1->getOperand(DI)->getType(),
- PN->getNumOperands());
- }
- for (auto &I : PN->operands())
- NewPN->addIncoming(cast<GEPOperator>(I)->getOperand(DI),
- PN->getIncomingBlock(I));
- NewGEP->setOperand(DI, NewPN);
- }
- GEP.getParent()->getInstList().insert(
- GEP.getParent()->getFirstInsertionPt(), NewGEP);
- replaceOperand(GEP, 0, NewGEP);
- PtrOp = NewGEP;
- }
- if (auto *Src = dyn_cast<GEPOperator>(PtrOp))
- if (Instruction *I = visitGEPOfGEP(GEP, Src))
- return I;
-
-
- if (GEP.getNumIndices() == 1 && !IsGEPSrcEleScalable) {
- unsigned AS = GEP.getPointerAddressSpace();
- if (GEP.getOperand(1)->getType()->getScalarSizeInBits() ==
- DL.getIndexSizeInBits(AS)) {
- uint64_t TyAllocSize = DL.getTypeAllocSize(GEPEltType).getFixedSize();
- bool Matched = false;
- uint64_t C;
- Value *V = nullptr;
- if (TyAllocSize == 1) {
- V = GEP.getOperand(1);
- Matched = true;
- } else if (match(GEP.getOperand(1),
- m_AShr(m_Value(V), m_ConstantInt(C)))) {
- if (TyAllocSize == 1ULL << C)
- Matched = true;
- } else if (match(GEP.getOperand(1),
- m_SDiv(m_Value(V), m_ConstantInt(C)))) {
- if (TyAllocSize == C)
- Matched = true;
- }
-
-
-
- Value *Y;
- Value *X = GEP.getOperand(0);
- if (Matched &&
- match(V, m_Sub(m_PtrToInt(m_Value(Y)), m_PtrToInt(m_Specific(X)))) &&
- getUnderlyingObject(X) == getUnderlyingObject(Y))
- return CastInst::CreatePointerBitCastOrAddrSpaceCast(Y, GEPType);
- }
- }
-
- if (GEPType->isVectorTy())
- return nullptr;
-
- Value *StrippedPtr = PtrOp->stripPointerCasts();
- PointerType *StrippedPtrTy = cast<PointerType>(StrippedPtr->getType());
-
-
-
-
- if (StrippedPtr != PtrOp && !StrippedPtrTy->isOpaque()) {
- bool HasZeroPointerIndex = false;
- Type *StrippedPtrEltTy = StrippedPtrTy->getNonOpaquePointerElementType();
- if (auto *C = dyn_cast<ConstantInt>(GEP.getOperand(1)))
- HasZeroPointerIndex = C->isZero();
-
-
-
-
-
-
-
- if (HasZeroPointerIndex) {
- if (auto *CATy = dyn_cast<ArrayType>(GEPEltType)) {
-
- if (CATy->getElementType() == StrippedPtrEltTy) {
-
- SmallVector<Value *, 8> Idx(drop_begin(GEP.indices()));
- GetElementPtrInst *Res = GetElementPtrInst::Create(
- StrippedPtrEltTy, StrippedPtr, Idx, GEP.getName());
- Res->setIsInBounds(GEP.isInBounds());
- if (StrippedPtrTy->getAddressSpace() == GEP.getAddressSpace())
- return Res;
-
-
-
-
-
-
- return new AddrSpaceCastInst(Builder.Insert(Res), GEPType);
- }
- if (auto *XATy = dyn_cast<ArrayType>(StrippedPtrEltTy)) {
-
- if (CATy->getElementType() == XATy->getElementType()) {
-
-
-
-
-
- if (StrippedPtrTy->getAddressSpace() == GEP.getAddressSpace()) {
- GEP.setSourceElementType(XATy);
- return replaceOperand(GEP, 0, StrippedPtr);
- }
-
-
-
-
-
-
-
-
-
- SmallVector<Value *, 8> Idx(GEP.indices());
- Value *NewGEP =
- GEP.isInBounds()
- ? Builder.CreateInBoundsGEP(StrippedPtrEltTy, StrippedPtr,
- Idx, GEP.getName())
- : Builder.CreateGEP(StrippedPtrEltTy, StrippedPtr, Idx,
- GEP.getName());
- return new AddrSpaceCastInst(NewGEP, GEPType);
- }
- }
- }
- } else if (GEP.getNumOperands() == 2 && !IsGEPSrcEleScalable) {
-
-
-
-
-
- if (StrippedPtrEltTy->isArrayTy() &&
- DL.getTypeAllocSize(StrippedPtrEltTy->getArrayElementType()) ==
- DL.getTypeAllocSize(GEPEltType)) {
- Type *IdxType = DL.getIndexType(GEPType);
- Value *Idx[2] = { Constant::getNullValue(IdxType), GEP.getOperand(1) };
- Value *NewGEP =
- GEP.isInBounds()
- ? Builder.CreateInBoundsGEP(StrippedPtrEltTy, StrippedPtr, Idx,
- GEP.getName())
- : Builder.CreateGEP(StrippedPtrEltTy, StrippedPtr, Idx,
- GEP.getName());
-
- return CastInst::CreatePointerBitCastOrAddrSpaceCast(NewGEP, GEPType);
- }
-
-
-
-
- if (GEPEltType->isSized() && StrippedPtrEltTy->isSized()) {
-
-
- uint64_t ResSize = DL.getTypeAllocSize(GEPEltType).getFixedSize();
- uint64_t SrcSize = DL.getTypeAllocSize(StrippedPtrEltTy).getFixedSize();
- if (ResSize && SrcSize % ResSize == 0) {
- Value *Idx = GEP.getOperand(1);
- unsigned BitWidth = Idx->getType()->getPrimitiveSizeInBits();
- uint64_t Scale = SrcSize / ResSize;
-
-
-
- assert(Idx->getType() == DL.getIndexType(GEPType) &&
- "Index type does not match the Data Layout preferences");
- bool NSW;
- if (Value *NewIdx = Descale(Idx, APInt(BitWidth, Scale), NSW)) {
-
-
-
- Value *NewGEP =
- GEP.isInBounds() && NSW
- ? Builder.CreateInBoundsGEP(StrippedPtrEltTy, StrippedPtr,
- NewIdx, GEP.getName())
- : Builder.CreateGEP(StrippedPtrEltTy, StrippedPtr, NewIdx,
- GEP.getName());
-
- return CastInst::CreatePointerBitCastOrAddrSpaceCast(NewGEP,
- GEPType);
- }
- }
- }
-
-
-
-
- if (GEPEltType->isSized() && StrippedPtrEltTy->isSized() &&
- StrippedPtrEltTy->isArrayTy()) {
-
-
- uint64_t ResSize = DL.getTypeAllocSize(GEPEltType).getFixedSize();
- uint64_t ArrayEltSize =
- DL.getTypeAllocSize(StrippedPtrEltTy->getArrayElementType())
- .getFixedSize();
- if (ResSize && ArrayEltSize % ResSize == 0) {
- Value *Idx = GEP.getOperand(1);
- unsigned BitWidth = Idx->getType()->getPrimitiveSizeInBits();
- uint64_t Scale = ArrayEltSize / ResSize;
-
-
-
- assert(Idx->getType() == DL.getIndexType(GEPType) &&
- "Index type does not match the Data Layout preferences");
- bool NSW;
- if (Value *NewIdx = Descale(Idx, APInt(BitWidth, Scale), NSW)) {
-
-
-
- Type *IndTy = DL.getIndexType(GEPType);
- Value *Off[2] = {Constant::getNullValue(IndTy), NewIdx};
- Value *NewGEP =
- GEP.isInBounds() && NSW
- ? Builder.CreateInBoundsGEP(StrippedPtrEltTy, StrippedPtr,
- Off, GEP.getName())
- : Builder.CreateGEP(StrippedPtrEltTy, StrippedPtr, Off,
- GEP.getName());
-
- return CastInst::CreatePointerBitCastOrAddrSpaceCast(NewGEP,
- GEPType);
- }
- }
- }
- }
- }
-
-
-
- Value *ASCStrippedPtrOp = PtrOp;
- if (auto *ASC = dyn_cast<AddrSpaceCastInst>(PtrOp)) {
-
-
-
-
- if (auto *BC = dyn_cast<BitCastInst>(ASC->getOperand(0)))
- ASCStrippedPtrOp = BC;
- }
- if (auto *BCI = dyn_cast<BitCastInst>(ASCStrippedPtrOp))
- if (Instruction *I = visitGEPOfBitcast(BCI, GEP))
- return I;
- if (!GEP.isInBounds()) {
- unsigned IdxWidth =
- DL.getIndexSizeInBits(PtrOp->getType()->getPointerAddressSpace());
- APInt BasePtrOffset(IdxWidth, 0);
- Value *UnderlyingPtrOp =
- PtrOp->stripAndAccumulateInBoundsConstantOffsets(DL,
- BasePtrOffset);
- if (auto *AI = dyn_cast<AllocaInst>(UnderlyingPtrOp)) {
- if (GEP.accumulateConstantOffset(DL, BasePtrOffset) &&
- BasePtrOffset.isNonNegative()) {
- APInt AllocSize(
- IdxWidth,
- DL.getTypeAllocSize(AI->getAllocatedType()).getKnownMinSize());
- if (BasePtrOffset.ule(AllocSize)) {
- return GetElementPtrInst::CreateInBounds(
- GEP.getSourceElementType(), PtrOp, Indices, GEP.getName());
- }
- }
- }
- }
- if (Instruction *R = foldSelectGEP(GEP, Builder))
- return R;
- return nullptr;
- }
- static bool isNeverEqualToUnescapedAlloc(Value *V, const TargetLibraryInfo &TLI,
- Instruction *AI) {
- if (isa<ConstantPointerNull>(V))
- return true;
- if (auto *LI = dyn_cast<LoadInst>(V))
- return isa<GlobalVariable>(LI->getPointerOperand());
-
- return isAllocLikeFn(V, &TLI) && V != AI;
- }
- static bool isRemovableWrite(CallBase &CB, Value *UsedV,
- const TargetLibraryInfo &TLI) {
- if (!CB.use_empty())
-
- return false;
- if (CB.isTerminator())
-
- return false;
- if (!CB.willReturn() || !CB.doesNotThrow())
- return false;
-
-
-
- Optional<MemoryLocation> Dest = MemoryLocation::getForDest(&CB, TLI);
- return Dest && Dest->Ptr == UsedV;
- }
- static bool isAllocSiteRemovable(Instruction *AI,
- SmallVectorImpl<WeakTrackingVH> &Users,
- const TargetLibraryInfo &TLI) {
- SmallVector<Instruction*, 4> Worklist;
- Worklist.push_back(AI);
- do {
- Instruction *PI = Worklist.pop_back_val();
- for (User *U : PI->users()) {
- Instruction *I = cast<Instruction>(U);
- switch (I->getOpcode()) {
- default:
-
- return false;
- case Instruction::AddrSpaceCast:
- case Instruction::BitCast:
- case Instruction::GetElementPtr:
- Users.emplace_back(I);
- Worklist.push_back(I);
- continue;
- case Instruction::ICmp: {
- ICmpInst *ICI = cast<ICmpInst>(I);
-
-
-
- if (!ICI->isEquality())
- return false;
- unsigned OtherIndex = (ICI->getOperand(0) == PI) ? 1 : 0;
- if (!isNeverEqualToUnescapedAlloc(ICI->getOperand(OtherIndex), TLI, AI))
- return false;
- Users.emplace_back(I);
- continue;
- }
- case Instruction::Call:
-
- if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
- switch (II->getIntrinsicID()) {
- default:
- return false;
- case Intrinsic::memmove:
- case Intrinsic::memcpy:
- case Intrinsic::memset: {
- MemIntrinsic *MI = cast<MemIntrinsic>(II);
- if (MI->isVolatile() || MI->getRawDest() != PI)
- return false;
- LLVM_FALLTHROUGH;
- }
- case Intrinsic::assume:
- case Intrinsic::invariant_start:
- case Intrinsic::invariant_end:
- case Intrinsic::lifetime_start:
- case Intrinsic::lifetime_end:
- case Intrinsic::objectsize:
- Users.emplace_back(I);
- continue;
- case Intrinsic::launder_invariant_group:
- case Intrinsic::strip_invariant_group:
- Users.emplace_back(I);
- Worklist.push_back(I);
- continue;
- }
- }
- if (isRemovableWrite(*cast<CallBase>(I), PI, TLI)) {
- Users.emplace_back(I);
- continue;
- }
- if (isFreeCall(I, &TLI)) {
- Users.emplace_back(I);
- continue;
- }
- if (isReallocLikeFn(I, &TLI)) {
- Users.emplace_back(I);
- Worklist.push_back(I);
- continue;
- }
- return false;
- case Instruction::Store: {
- StoreInst *SI = cast<StoreInst>(I);
- if (SI->isVolatile() || SI->getPointerOperand() != PI)
- return false;
- Users.emplace_back(I);
- continue;
- }
- }
- llvm_unreachable("missing a return?");
- }
- } while (!Worklist.empty());
- return true;
- }
- Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
- assert(isa<AllocaInst>(MI) || isAllocRemovable(&cast<CallBase>(MI), &TLI));
-
-
-
-
-
-
-
-
-
- SmallVector<WeakTrackingVH, 64> Users;
-
-
- SmallVector<DbgVariableIntrinsic *, 8> DVIs;
- std::unique_ptr<DIBuilder> DIB;
- if (isa<AllocaInst>(MI)) {
- findDbgUsers(DVIs, &MI);
- DIB.reset(new DIBuilder(*MI.getModule(), false));
- }
- if (isAllocSiteRemovable(&MI, Users, TLI)) {
- for (unsigned i = 0, e = Users.size(); i != e; ++i) {
-
-
- if (!Users[i])
- continue;
- Instruction *I = cast<Instruction>(&*Users[i]);
- if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
- if (II->getIntrinsicID() == Intrinsic::objectsize) {
- Value *Result =
- lowerObjectSizeCall(II, DL, &TLI, true);
- replaceInstUsesWith(*I, Result);
- eraseInstFromFunction(*I);
- Users[i] = nullptr;
- }
- }
- }
- for (unsigned i = 0, e = Users.size(); i != e; ++i) {
- if (!Users[i])
- continue;
- Instruction *I = cast<Instruction>(&*Users[i]);
- if (ICmpInst *C = dyn_cast<ICmpInst>(I)) {
- replaceInstUsesWith(*C,
- ConstantInt::get(Type::getInt1Ty(C->getContext()),
- C->isFalseWhenEqual()));
- } else if (auto *SI = dyn_cast<StoreInst>(I)) {
- for (auto *DVI : DVIs)
- if (DVI->isAddressOfVariable())
- ConvertDebugDeclareToDebugValue(DVI, SI, *DIB);
- } else {
-
-
- replaceInstUsesWith(*I, PoisonValue::get(I->getType()));
- }
- eraseInstFromFunction(*I);
- }
- if (InvokeInst *II = dyn_cast<InvokeInst>(&MI)) {
-
- Module *M = II->getModule();
- Function *F = Intrinsic::getDeclaration(M, Intrinsic::donothing);
- InvokeInst::Create(F, II->getNormalDest(), II->getUnwindDest(),
- None, "", II->getParent());
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- for (auto *DVI : DVIs)
- if (DVI->isAddressOfVariable() || DVI->getExpression()->startsWithDeref())
- DVI->eraseFromParent();
- return eraseInstFromFunction(MI);
- }
- return nullptr;
- }
- static Instruction *tryToMoveFreeBeforeNullTest(CallInst &FI,
- const DataLayout &DL) {
- Value *Op = FI.getArgOperand(0);
- BasicBlock *FreeInstrBB = FI.getParent();
- BasicBlock *PredBB = FreeInstrBB->getSinglePredecessor();
-
-
-
-
- if (!PredBB)
- return nullptr;
-
-
- BasicBlock *SuccBB;
- Instruction *FreeInstrBBTerminator = FreeInstrBB->getTerminator();
- if (!match(FreeInstrBBTerminator, m_UnconditionalBr(SuccBB)))
- return nullptr;
-
-
-
-
- if (FreeInstrBB->size() != 2) {
- for (const Instruction &Inst : FreeInstrBB->instructionsWithoutDebug()) {
- if (&Inst == &FI || &Inst == FreeInstrBBTerminator)
- continue;
- auto *Cast = dyn_cast<CastInst>(&Inst);
- if (!Cast || !Cast->isNoopCast(DL))
- return nullptr;
- }
- }
-
- Instruction *TI = PredBB->getTerminator();
- BasicBlock *TrueBB, *FalseBB;
- ICmpInst::Predicate Pred;
- if (!match(TI, m_Br(m_ICmp(Pred,
- m_CombineOr(m_Specific(Op),
- m_Specific(Op->stripPointerCasts())),
- m_Zero()),
- TrueBB, FalseBB)))
- return nullptr;
- if (Pred != ICmpInst::ICMP_EQ && Pred != ICmpInst::ICMP_NE)
- return nullptr;
-
- if (SuccBB != (Pred == ICmpInst::ICMP_EQ ? TrueBB : FalseBB))
- return nullptr;
- assert(FreeInstrBB == (Pred == ICmpInst::ICMP_EQ ? FalseBB : TrueBB) &&
- "Broken CFG: missing edge from predecessor to successor");
-
-
- for (Instruction &Instr : llvm::make_early_inc_range(*FreeInstrBB)) {
- if (&Instr == FreeInstrBBTerminator)
- break;
- Instr.moveBefore(TI);
- }
- assert(FreeInstrBB->size() == 1 &&
- "Only the branch instruction should remain");
-
-
-
-
-
-
-
-
- AttributeList Attrs = FI.getAttributes();
- Attrs = Attrs.removeParamAttribute(FI.getContext(), 0, Attribute::NonNull);
- Attribute Dereferenceable = Attrs.getParamAttr(0, Attribute::Dereferenceable);
- if (Dereferenceable.isValid()) {
- uint64_t Bytes = Dereferenceable.getDereferenceableBytes();
- Attrs = Attrs.removeParamAttribute(FI.getContext(), 0,
- Attribute::Dereferenceable);
- Attrs = Attrs.addDereferenceableOrNullParamAttr(FI.getContext(), 0, Bytes);
- }
- FI.setAttributes(Attrs);
- return &FI;
- }
- Instruction *InstCombinerImpl::visitFree(CallInst &FI) {
- Value *Op = FI.getArgOperand(0);
-
- if (isa<UndefValue>(Op)) {
-
- CreateNonTerminatorUnreachable(&FI);
- return eraseInstFromFunction(FI);
- }
-
-
- if (isa<ConstantPointerNull>(Op))
- return eraseInstFromFunction(FI);
-
-
- if (CallInst *CI = dyn_cast<CallInst>(Op)) {
- if (CI->hasOneUse() && isReallocLikeFn(CI, &TLI)) {
- return eraseInstFromFunction(
- *replaceInstUsesWith(*CI, CI->getOperand(0)));
- }
- }
-
-
-
-
-
-
-
-
-
-
- if (MinimizeSize) {
- LibFunc Func;
- if (TLI.getLibFunc(FI, Func) && TLI.has(Func) && Func == LibFunc_free)
- if (Instruction *I = tryToMoveFreeBeforeNullTest(FI, DL))
- return I;
- }
- return nullptr;
- }
- static bool isMustTailCall(Value *V) {
- if (auto *CI = dyn_cast<CallInst>(V))
- return CI->isMustTailCall();
- return false;
- }
- Instruction *InstCombinerImpl::visitReturnInst(ReturnInst &RI) {
- if (RI.getNumOperands() == 0)
- return nullptr;
- Value *ResultOp = RI.getOperand(0);
- Type *VTy = ResultOp->getType();
- if (!VTy->isIntegerTy() || isa<Constant>(ResultOp))
- return nullptr;
-
- if (isMustTailCall(ResultOp))
- return nullptr;
-
-
- KnownBits Known = computeKnownBits(ResultOp, 0, &RI);
- if (Known.isConstant())
- return replaceOperand(RI, 0,
- Constant::getIntegerValue(VTy, Known.getConstant()));
- return nullptr;
- }
- Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
-
-
-
- while (Instruction *Prev = I.getPrevNonDebugInstruction()) {
-
-
-
-
- if (Prev->isEHPad())
- return nullptr;
- if (!isGuaranteedToTransferExecutionToSuccessor(Prev))
- return nullptr;
-
-
-
-
- replaceInstUsesWith(*Prev, PoisonValue::get(Prev->getType()));
- eraseInstFromFunction(*Prev);
- }
- assert(I.getParent()->sizeWithoutDebug() == 1 && "The block is now empty.");
-
- return nullptr;
- }
- Instruction *InstCombinerImpl::visitUnconditionalBranchInst(BranchInst &BI) {
- assert(BI.isUnconditional() && "Only for unconditional branches.");
-
-
-
- auto GetLastSinkableStore = [](BasicBlock::iterator BBI) {
- auto IsNoopInstrForStoreMerging = [](BasicBlock::iterator BBI) {
- return BBI->isDebugOrPseudoInst() ||
- (isa<BitCastInst>(BBI) && BBI->getType()->isPointerTy());
- };
- BasicBlock::iterator FirstInstr = BBI->getParent()->begin();
- do {
- if (BBI != FirstInstr)
- --BBI;
- } while (BBI != FirstInstr && IsNoopInstrForStoreMerging(BBI));
- return dyn_cast<StoreInst>(BBI);
- };
- if (StoreInst *SI = GetLastSinkableStore(BasicBlock::iterator(BI)))
- if (mergeStoreIntoSuccessor(*SI))
- return &BI;
- return nullptr;
- }
- Instruction *InstCombinerImpl::visitBranchInst(BranchInst &BI) {
- if (BI.isUnconditional())
- return visitUnconditionalBranchInst(BI);
-
- Value *X = nullptr;
- if (match(&BI, m_Br(m_Not(m_Value(X)), m_BasicBlock(), m_BasicBlock())) &&
- !isa<Constant>(X)) {
-
- BI.swapSuccessors();
- return replaceOperand(BI, 0, X);
- }
-
-
- if (!isa<ConstantInt>(BI.getCondition()) &&
- BI.getSuccessor(0) == BI.getSuccessor(1))
- return replaceOperand(
- BI, 0, ConstantInt::getFalse(BI.getCondition()->getType()));
-
- CmpInst::Predicate Pred;
- if (match(&BI, m_Br(m_OneUse(m_FCmp(Pred, m_Value(), m_Value())),
- m_BasicBlock(), m_BasicBlock())) &&
- !isCanonicalPredicate(Pred)) {
-
- CmpInst *Cond = cast<CmpInst>(BI.getCondition());
- Cond->setPredicate(CmpInst::getInversePredicate(Pred));
- BI.swapSuccessors();
- Worklist.push(Cond);
- return &BI;
- }
- return nullptr;
- }
- Instruction *InstCombinerImpl::visitSwitchInst(SwitchInst &SI) {
- Value *Cond = SI.getCondition();
- Value *Op0;
- ConstantInt *AddRHS;
- if (match(Cond, m_Add(m_Value(Op0), m_ConstantInt(AddRHS)))) {
-
- for (auto Case : SI.cases()) {
- Constant *NewCase = ConstantExpr::getSub(Case.getCaseValue(), AddRHS);
- assert(isa<ConstantInt>(NewCase) &&
- "Result of expression should be constant");
- Case.setValue(cast<ConstantInt>(NewCase));
- }
- return replaceOperand(SI, 0, Op0);
- }
- KnownBits Known = computeKnownBits(Cond, 0, &SI);
- unsigned LeadingKnownZeros = Known.countMinLeadingZeros();
- unsigned LeadingKnownOnes = Known.countMinLeadingOnes();
-
-
- for (auto &C : SI.cases()) {
- LeadingKnownZeros = std::min(
- LeadingKnownZeros, C.getCaseValue()->getValue().countLeadingZeros());
- LeadingKnownOnes = std::min(
- LeadingKnownOnes, C.getCaseValue()->getValue().countLeadingOnes());
- }
- unsigned NewWidth = Known.getBitWidth() - std::max(LeadingKnownZeros, LeadingKnownOnes);
-
-
-
-
- if (NewWidth > 0 && NewWidth < Known.getBitWidth() &&
- shouldChangeType(Known.getBitWidth(), NewWidth)) {
- IntegerType *Ty = IntegerType::get(SI.getContext(), NewWidth);
- Builder.SetInsertPoint(&SI);
- Value *NewCond = Builder.CreateTrunc(Cond, Ty, "trunc");
- for (auto Case : SI.cases()) {
- APInt TruncatedCase = Case.getCaseValue()->getValue().trunc(NewWidth);
- Case.setValue(ConstantInt::get(SI.getContext(), TruncatedCase));
- }
- return replaceOperand(SI, 0, NewCond);
- }
- return nullptr;
- }
- Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
- Value *Agg = EV.getAggregateOperand();
- if (!EV.hasIndices())
- return replaceInstUsesWith(EV, Agg);
- if (Value *V = SimplifyExtractValueInst(Agg, EV.getIndices(),
- SQ.getWithInstruction(&EV)))
- return replaceInstUsesWith(EV, V);
- if (InsertValueInst *IV = dyn_cast<InsertValueInst>(Agg)) {
-
- const unsigned *exti, *exte, *insi, *inse;
- for (exti = EV.idx_begin(), insi = IV->idx_begin(),
- exte = EV.idx_end(), inse = IV->idx_end();
- exti != exte && insi != inse;
- ++exti, ++insi) {
- if (*insi != *exti)
-
-
-
-
-
-
-
-
- return ExtractValueInst::Create(IV->getAggregateOperand(),
- EV.getIndices());
- }
- if (exti == exte && insi == inse)
-
-
-
-
- return replaceInstUsesWith(EV, IV->getInsertedValueOperand());
- if (exti == exte) {
-
-
-
-
-
-
-
-
- Value *NewEV = Builder.CreateExtractValue(IV->getAggregateOperand(),
- EV.getIndices());
- return InsertValueInst::Create(NewEV, IV->getInsertedValueOperand(),
- makeArrayRef(insi, inse));
- }
- if (insi == inse)
-
-
-
-
-
-
-
-
- return ExtractValueInst::Create(IV->getInsertedValueOperand(),
- makeArrayRef(exti, exte));
- }
- if (WithOverflowInst *WO = dyn_cast<WithOverflowInst>(Agg)) {
-
-
-
- if (WO->hasOneUse()) {
-
-
- if (*EV.idx_begin() == 0) {
- Instruction::BinaryOps BinOp = WO->getBinaryOp();
- Value *LHS = WO->getLHS(), *RHS = WO->getRHS();
-
- replaceInstUsesWith(*WO, PoisonValue::get(WO->getType()));
- eraseInstFromFunction(*WO);
- return BinaryOperator::Create(BinOp, LHS, RHS);
- }
- assert(*EV.idx_begin() == 1 &&
- "unexpected extract index for overflow inst");
-
-
-
- const APInt *C;
- if (match(WO->getRHS(), m_APInt(C))) {
-
-
- ConstantRange NWR =
- ConstantRange::makeExactNoWrapRegion(WO->getBinaryOp(), *C,
- WO->getNoWrapKind());
- CmpInst::Predicate Pred;
- APInt NewRHSC, Offset;
- NWR.getEquivalentICmp(Pred, NewRHSC, Offset);
- auto *OpTy = WO->getRHS()->getType();
- auto *NewLHS = WO->getLHS();
- if (Offset != 0)
- NewLHS = Builder.CreateAdd(NewLHS, ConstantInt::get(OpTy, Offset));
- return new ICmpInst(ICmpInst::getInversePredicate(Pred), NewLHS,
- ConstantInt::get(OpTy, NewRHSC));
- }
- }
- }
- if (LoadInst *L = dyn_cast<LoadInst>(Agg))
-
-
-
-
-
- if (L->isSimple() && L->hasOneUse()) {
-
- SmallVector<Value*, 4> Indices;
-
- Indices.push_back(Builder.getInt32(0));
- for (unsigned Idx : EV.indices())
- Indices.push_back(Builder.getInt32(Idx));
-
-
- Builder.SetInsertPoint(L);
- Value *GEP = Builder.CreateInBoundsGEP(L->getType(),
- L->getPointerOperand(), Indices);
- Instruction *NL = Builder.CreateLoad(EV.getType(), GEP);
-
-
- NL->setAAMetadata(L->getAAMetadata());
-
-
- return replaceInstUsesWith(EV, NL);
- }
-
-
-
-
-
-
-
-
- return nullptr;
- }
- static bool isCatchAll(EHPersonality Personality, Constant *TypeInfo) {
- switch (Personality) {
- case EHPersonality::GNU_C:
- case EHPersonality::GNU_C_SjLj:
- case EHPersonality::Rust:
-
-
- return false;
- case EHPersonality::Unknown:
- return false;
- case EHPersonality::GNU_Ada:
-
-
- return false;
- case EHPersonality::GNU_CXX:
- case EHPersonality::GNU_CXX_SjLj:
- case EHPersonality::GNU_ObjC:
- case EHPersonality::MSVC_X86SEH:
- case EHPersonality::MSVC_TableSEH:
- case EHPersonality::MSVC_CXX:
- case EHPersonality::CoreCLR:
- case EHPersonality::Wasm_CXX:
- case EHPersonality::XL_CXX:
- return TypeInfo->isNullValue();
- }
- llvm_unreachable("invalid enum");
- }
- static bool shorter_filter(const Value *LHS, const Value *RHS) {
- return
- cast<ArrayType>(LHS->getType())->getNumElements()
- <
- cast<ArrayType>(RHS->getType())->getNumElements();
- }
- Instruction *InstCombinerImpl::visitLandingPadInst(LandingPadInst &LI) {
-
-
-
- EHPersonality Personality =
- classifyEHPersonality(LI.getParent()->getParent()->getPersonalityFn());
-
-
- bool MakeNewInstruction = false;
- SmallVector<Constant *, 16> NewClauses;
- bool CleanupFlag = LI.isCleanup();
- SmallPtrSet<Value *, 16> AlreadyCaught;
- for (unsigned i = 0, e = LI.getNumClauses(); i != e; ++i) {
- bool isLastClause = i + 1 == e;
- if (LI.isCatch(i)) {
-
- Constant *CatchClause = LI.getClause(i);
- Constant *TypeInfo = CatchClause->stripPointerCasts();
-
-
- if (AlreadyCaught.insert(TypeInfo).second) {
-
- NewClauses.push_back(CatchClause);
- } else {
-
- MakeNewInstruction = true;
- }
-
-
- if (isCatchAll(Personality, TypeInfo)) {
- if (!isLastClause)
- MakeNewInstruction = true;
- CleanupFlag = false;
- break;
- }
- } else {
-
-
-
-
-
-
-
- assert(LI.isFilter(i) && "Unsupported landingpad clause!");
- Constant *FilterClause = LI.getClause(i);
- ArrayType *FilterType = cast<ArrayType>(FilterClause->getType());
- unsigned NumTypeInfos = FilterType->getNumElements();
-
-
-
- if (!NumTypeInfos) {
- NewClauses.push_back(FilterClause);
- if (!isLastClause)
- MakeNewInstruction = true;
- CleanupFlag = false;
- break;
- }
- bool MakeNewFilter = false;
- SmallVector<Constant *, 16> NewFilterElts;
- if (isa<ConstantAggregateZero>(FilterClause)) {
-
- assert(NumTypeInfos > 0 && "Should have handled empty filter already!");
- Constant *TypeInfo =
- Constant::getNullValue(FilterType->getElementType());
-
- if (isCatchAll(Personality, TypeInfo)) {
-
- MakeNewInstruction = true;
- continue;
- }
-
-
- NewFilterElts.push_back(TypeInfo);
- if (NumTypeInfos > 1)
- MakeNewFilter = true;
- } else {
- ConstantArray *Filter = cast<ConstantArray>(FilterClause);
- SmallPtrSet<Value *, 16> SeenInFilter;
- NewFilterElts.reserve(NumTypeInfos);
-
-
-
- bool SawCatchAll = false;
- for (unsigned j = 0; j != NumTypeInfos; ++j) {
- Constant *Elt = Filter->getOperand(j);
- Constant *TypeInfo = Elt->stripPointerCasts();
- if (isCatchAll(Personality, TypeInfo)) {
-
- SawCatchAll = true;
- break;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if (SeenInFilter.insert(TypeInfo).second)
- NewFilterElts.push_back(cast<Constant>(Elt));
- }
-
- if (SawCatchAll) {
-
- MakeNewInstruction = true;
- continue;
- }
-
- if (NewFilterElts.size() < NumTypeInfos)
- MakeNewFilter = true;
- }
- if (MakeNewFilter) {
- FilterType = ArrayType::get(FilterType->getElementType(),
- NewFilterElts.size());
- FilterClause = ConstantArray::get(FilterType, NewFilterElts);
- MakeNewInstruction = true;
- }
- NewClauses.push_back(FilterClause);
-
-
-
-
- if (MakeNewFilter && !NewFilterElts.size()) {
- assert(MakeNewInstruction && "New filter but not a new instruction!");
- CleanupFlag = false;
- break;
- }
- }
- }
-
-
-
-
-
- for (unsigned i = 0, e = NewClauses.size(); i + 1 < e; ) {
- unsigned j;
-
- for (j = i; j != e; ++j)
- if (!isa<ArrayType>(NewClauses[j]->getType()))
- break;
-
-
-
- for (unsigned k = i; k + 1 < j; ++k)
- if (shorter_filter(NewClauses[k+1], NewClauses[k])) {
-
-
- std::stable_sort(NewClauses.begin() + i, NewClauses.begin() + j,
- shorter_filter);
- MakeNewInstruction = true;
- break;
- }
-
- i = j + 1;
- }
-
-
-
-
-
-
-
-
-
-
-
- for (unsigned i = 0; i + 1 < NewClauses.size(); ++i) {
-
- Value *Filter = NewClauses[i];
- ArrayType *FTy = dyn_cast<ArrayType>(Filter->getType());
- if (!FTy)
-
- continue;
- unsigned FElts = FTy->getNumElements();
-
-
- for (unsigned j = NewClauses.size() - 1; j != i; --j) {
- Value *LFilter = NewClauses[j];
- ArrayType *LTy = dyn_cast<ArrayType>(LFilter->getType());
- if (!LTy)
-
- continue;
-
-
- SmallVectorImpl<Constant *>::iterator J = NewClauses.begin() + j;
-
- if (!FElts) {
-
- NewClauses.erase(J);
- MakeNewInstruction = true;
-
- continue;
- }
- unsigned LElts = LTy->getNumElements();
-
- if (FElts > LElts)
-
- continue;
-
- if (isa<ConstantAggregateZero>(LFilter)) {
-
-
- if (isa<ConstantAggregateZero>(Filter)) {
- assert(FElts <= LElts && "Should have handled this case earlier!");
-
- NewClauses.erase(J);
- MakeNewInstruction = true;
- }
-
- continue;
- }
- ConstantArray *LArray = cast<ConstantArray>(LFilter);
- if (isa<ConstantAggregateZero>(Filter)) {
-
-
- assert(FElts > 0 && "Should have eliminated the empty filter earlier!");
- for (unsigned l = 0; l != LElts; ++l)
- if (LArray->getOperand(l)->isNullValue()) {
-
- NewClauses.erase(J);
- MakeNewInstruction = true;
- break;
- }
-
- continue;
- }
-
-
-
-
- ConstantArray *FArray = cast<ConstantArray>(Filter);
- bool AllFound = true;
- for (unsigned f = 0; f != FElts; ++f) {
- Value *FTypeInfo = FArray->getOperand(f)->stripPointerCasts();
- AllFound = false;
- for (unsigned l = 0; l != LElts; ++l) {
- Value *LTypeInfo = LArray->getOperand(l)->stripPointerCasts();
- if (LTypeInfo == FTypeInfo) {
- AllFound = true;
- break;
- }
- }
- if (!AllFound)
- break;
- }
- if (AllFound) {
-
- NewClauses.erase(J);
- MakeNewInstruction = true;
- }
-
- }
- }
-
-
- if (MakeNewInstruction) {
- LandingPadInst *NLI = LandingPadInst::Create(LI.getType(),
- NewClauses.size());
- for (unsigned i = 0, e = NewClauses.size(); i != e; ++i)
- NLI->addClause(NewClauses[i]);
-
-
-
- if (NewClauses.empty())
- CleanupFlag = true;
- NLI->setCleanup(CleanupFlag);
- return NLI;
- }
-
-
- if (LI.isCleanup() != CleanupFlag) {
- assert(!CleanupFlag && "Adding a cleanup, not removing one?!");
- LI.setCleanup(CleanupFlag);
- return &LI;
- }
- return nullptr;
- }
- Value *
- InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating(FreezeInst &OrigFI) {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- auto *OrigOp = OrigFI.getOperand(0);
- auto *OrigOpInst = dyn_cast<Instruction>(OrigOp);
-
-
-
- if (!OrigOpInst || !OrigOpInst->hasOneUse() || isa<PHINode>(OrigOp))
- return nullptr;
-
-
-
-
- if (canCreateUndefOrPoison(cast<Operator>(OrigOp), false))
- return nullptr;
-
-
-
- Use *MaybePoisonOperand = nullptr;
- for (Use &U : OrigOpInst->operands()) {
- if (isGuaranteedNotToBeUndefOrPoison(U.get()))
- continue;
- if (!MaybePoisonOperand)
- MaybePoisonOperand = &U;
- else
- return nullptr;
- }
- OrigOpInst->dropPoisonGeneratingFlags();
-
- if (!MaybePoisonOperand)
- return OrigOp;
- auto *FrozenMaybePoisonOperand = new FreezeInst(
- MaybePoisonOperand->get(), MaybePoisonOperand->get()->getName() + ".fr");
- replaceUse(*MaybePoisonOperand, FrozenMaybePoisonOperand);
- FrozenMaybePoisonOperand->insertBefore(OrigOpInst);
- return OrigOp;
- }
- bool InstCombinerImpl::freezeDominatedUses(FreezeInst &FI) {
- Value *Op = FI.getOperand(0);
- if (isa<Constant>(Op))
- return false;
- bool Changed = false;
- Op->replaceUsesWithIf(&FI, [&](Use &U) -> bool {
- bool Dominates = DT.dominates(&FI, U);
- Changed |= Dominates;
- return Dominates;
- });
- return Changed;
- }
- Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
- Value *Op0 = I.getOperand(0);
- if (Value *V = SimplifyFreezeInst(Op0, SQ.getWithInstruction(&I)))
- return replaceInstUsesWith(I, V);
-
- if (auto *PN = dyn_cast<PHINode>(Op0)) {
- if (Instruction *NV = foldOpIntoPhi(I, PN))
- return NV;
- }
- if (Value *NI = pushFreezeToPreventPoisonFromPropagating(I))
- return replaceInstUsesWith(I, NI);
- if (match(Op0, m_Undef())) {
-
-
-
-
- Constant *BestValue = nullptr;
- Constant *NullValue = Constant::getNullValue(I.getType());
- for (const auto *U : I.users()) {
- Constant *C = NullValue;
- if (match(U, m_Or(m_Value(), m_Value())))
- C = Constant::getAllOnesValue(I.getType());
- else if (const auto *SI = dyn_cast<SelectInst>(U)) {
- if (SI->getCondition() == &I) {
- APInt CondVal(1, isa<Constant>(SI->getFalseValue()) ? 0 : 1);
- C = Constant::getIntegerValue(I.getType(), CondVal);
- }
- }
- if (!BestValue)
- BestValue = C;
- else if (BestValue != C)
- BestValue = NullValue;
- }
- return replaceInstUsesWith(I, BestValue);
- }
-
- if (freezeDominatedUses(I))
- return &I;
- return nullptr;
- }
- static bool SoleWriteToDeadLocal(Instruction *I, TargetLibraryInfo &TLI) {
- auto *CB = dyn_cast<CallBase>(I);
- if (!CB)
-
-
-
- return false;
- Optional<MemoryLocation> Dest = MemoryLocation::getForDest(CB, TLI);
- if (!Dest)
- return false;
- auto *AI = dyn_cast<AllocaInst>(getUnderlyingObject(Dest->Ptr));
- if (!AI)
-
- return false;
-
-
-
- SmallVector<const User *> AllocaUsers;
- SmallPtrSet<const User *, 4> Visited;
- auto pushUsers = [&](const Instruction &I) {
- for (const User *U : I.users()) {
- if (Visited.insert(U).second)
- AllocaUsers.push_back(U);
- }
- };
- pushUsers(*AI);
- while (!AllocaUsers.empty()) {
- auto *UserI = cast<Instruction>(AllocaUsers.pop_back_val());
- if (isa<BitCastInst>(UserI) || isa<GetElementPtrInst>(UserI) ||
- isa<AddrSpaceCastInst>(UserI)) {
- pushUsers(*UserI);
- continue;
- }
- if (UserI == CB)
- continue;
-
- return false;
- }
- return true;
- }
- static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock,
- TargetLibraryInfo &TLI) {
- assert(I->getUniqueUndroppableUser() && "Invariants didn't hold!");
- BasicBlock *SrcBlock = I->getParent();
-
- if (isa<PHINode>(I) || I->isEHPad() || I->mayThrow() || !I->willReturn() ||
- I->isTerminator())
- return false;
-
-
-
-
- if (isa<AllocaInst>(I))
- return false;
-
- if (isa<CatchSwitchInst>(DestBlock->getTerminator()))
- return false;
-
- if (auto *CI = dyn_cast<CallInst>(I)) {
- if (CI->isConvergent())
- return false;
- }
-
-
- if (I->mayWriteToMemory()) {
- if (!SoleWriteToDeadLocal(I, TLI))
- return false;
- }
-
-
- if (I->mayReadFromMemory()) {
-
-
-
- if (DestBlock->getUniquePredecessor() != I->getParent())
- return false;
- for (BasicBlock::iterator Scan = std::next(I->getIterator()),
- E = I->getParent()->end();
- Scan != E; ++Scan)
- if (Scan->mayWriteToMemory())
- return false;
- }
- I->dropDroppableUses([DestBlock](const Use *U) {
- if (auto *I = dyn_cast<Instruction>(U->getUser()))
- return I->getParent() != DestBlock;
- return true;
- });
-
-
- BasicBlock::iterator InsertPos = DestBlock->getFirstInsertionPt();
- I->moveBefore(&*InsertPos);
- ++NumSunkInst;
-
-
-
-
-
- SmallVector<DbgVariableIntrinsic *, 2> DbgUsers;
- findDbgUsers(DbgUsers, I);
-
-
- SmallVector<DbgVariableIntrinsic *, 2> DbgUsersToSink;
- for (DbgVariableIntrinsic *DVI : DbgUsers)
- if (DVI->getParent() == SrcBlock)
- DbgUsersToSink.push_back(DVI);
- llvm::sort(DbgUsersToSink,
- [](auto *A, auto *B) { return B->comesBefore(A); });
- SmallVector<DbgVariableIntrinsic *, 2> DIIClones;
- SmallSet<DebugVariable, 4> SunkVariables;
- for (auto User : DbgUsersToSink) {
-
-
-
-
- if (isa<DbgDeclareInst>(User))
- continue;
- DebugVariable DbgUserVariable =
- DebugVariable(User->getVariable(), User->getExpression(),
- User->getDebugLoc()->getInlinedAt());
- if (!SunkVariables.insert(DbgUserVariable).second)
- continue;
- DIIClones.emplace_back(cast<DbgVariableIntrinsic>(User->clone()));
- if (isa<DbgDeclareInst>(User) && isa<CastInst>(I))
- DIIClones.back()->replaceVariableLocationOp(I, I->getOperand(0));
- LLVM_DEBUG(dbgs() << "CLONE: " << *DIIClones.back() << '\n');
- }
-
- if (!DIIClones.empty()) {
- salvageDebugInfoForDbgValues(*I, DbgUsers);
-
-
- for (auto &DIIClone : llvm::reverse(DIIClones)) {
- DIIClone->insertBefore(&*InsertPos);
- LLVM_DEBUG(dbgs() << "SINK: " << *DIIClone << '\n');
- }
- }
- return true;
- }
- bool InstCombinerImpl::run() {
- while (!Worklist.isEmpty()) {
-
-
- while (Instruction *I = Worklist.popDeferred()) {
-
-
-
-
- if (isInstructionTriviallyDead(I, &TLI)) {
- eraseInstFromFunction(*I);
- ++NumDeadInst;
- continue;
- }
- Worklist.push(I);
- }
- Instruction *I = Worklist.removeOne();
- if (I == nullptr) continue;
-
- if (isInstructionTriviallyDead(I, &TLI)) {
- eraseInstFromFunction(*I);
- ++NumDeadInst;
- continue;
- }
- if (!DebugCounter::shouldExecute(VisitCounter))
- continue;
-
- if (!I->use_empty() &&
- (I->getNumOperands() == 0 || isa<Constant>(I->getOperand(0)))) {
- if (Constant *C = ConstantFoldInstruction(I, DL, &TLI)) {
- LLVM_DEBUG(dbgs() << "IC: ConstFold to: " << *C << " from: " << *I
- << '\n');
-
- replaceInstUsesWith(*I, C);
- ++NumConstProp;
- if (isInstructionTriviallyDead(I, &TLI))
- eraseInstFromFunction(*I);
- MadeIRChange = true;
- continue;
- }
- }
-
-
-
- auto getOptionalSinkBlockForInst =
- [this](Instruction *I) -> Optional<BasicBlock *> {
- if (!EnableCodeSinking)
- return None;
- auto *UserInst = cast_or_null<Instruction>(I->getUniqueUndroppableUser());
- if (!UserInst)
- return None;
- BasicBlock *BB = I->getParent();
- BasicBlock *UserParent = nullptr;
-
- if (PHINode *PN = dyn_cast<PHINode>(UserInst)) {
- for (unsigned i = 0; i < PN->getNumIncomingValues(); i++) {
- if (PN->getIncomingValue(i) == I) {
-
-
-
- if (UserParent && UserParent != PN->getIncomingBlock(i))
- return None;
- UserParent = PN->getIncomingBlock(i);
- }
- }
- assert(UserParent && "expected to find user block!");
- } else
- UserParent = UserInst->getParent();
-
-
- if (UserParent == BB || !DT.isReachableFromEntry(UserParent))
- return None;
- auto *Term = UserParent->getTerminator();
-
-
-
-
-
-
-
-
- if (UserParent->getUniquePredecessor() == BB || succ_empty(Term)) {
- assert(DT.dominates(BB, UserParent) && "Dominance relation broken?");
- return UserParent;
- }
- return None;
- };
- auto OptBB = getOptionalSinkBlockForInst(I);
- if (OptBB) {
- auto *UserParent = *OptBB;
-
- if (TryToSinkInstruction(I, UserParent, TLI)) {
- LLVM_DEBUG(dbgs() << "IC: Sink: " << *I << '\n');
- MadeIRChange = true;
-
-
-
- for (Use &U : I->operands())
- if (Instruction *OpI = dyn_cast<Instruction>(U.get()))
- Worklist.push(OpI);
- }
- }
-
- Builder.SetInsertPoint(I);
- Builder.CollectMetadataToCopy(
- I, {LLVMContext::MD_dbg, LLVMContext::MD_annotation});
- #ifndef NDEBUG
- std::string OrigI;
- #endif
- LLVM_DEBUG(raw_string_ostream SS(OrigI); I->print(SS); OrigI = SS.str(););
- LLVM_DEBUG(dbgs() << "IC: Visiting: " << OrigI << '\n');
- if (Instruction *Result = visit(*I)) {
- ++NumCombined;
-
- if (Result != I) {
- LLVM_DEBUG(dbgs() << "IC: Old = " << *I << '\n'
- << " New = " << *Result << '\n');
- Result->copyMetadata(*I,
- {LLVMContext::MD_dbg, LLVMContext::MD_annotation});
-
- I->replaceAllUsesWith(Result);
-
- Result->takeName(I);
-
- BasicBlock *InstParent = I->getParent();
- BasicBlock::iterator InsertPos = I->getIterator();
-
- if (isa<PHINode>(Result) != isa<PHINode>(I)) {
-
- if (isa<PHINode>(I))
- InsertPos = InstParent->getFirstInsertionPt();
- else
- InsertPos = InstParent->getFirstNonPHI()->getIterator();
- }
- InstParent->getInstList().insert(InsertPos, Result);
-
- Worklist.pushUsersToWorkList(*Result);
- Worklist.push(Result);
- eraseInstFromFunction(*I);
- } else {
- LLVM_DEBUG(dbgs() << "IC: Mod = " << OrigI << '\n'
- << " New = " << *I << '\n');
-
-
- if (isInstructionTriviallyDead(I, &TLI)) {
- eraseInstFromFunction(*I);
- } else {
- Worklist.pushUsersToWorkList(*I);
- Worklist.push(I);
- }
- }
- MadeIRChange = true;
- }
- }
- Worklist.zap();
- return MadeIRChange;
- }
- class AliasScopeTracker {
- SmallPtrSet<const MDNode *, 8> UsedAliasScopesAndLists;
- SmallPtrSet<const MDNode *, 8> UsedNoAliasScopesAndLists;
- public:
- void analyse(Instruction *I) {
-
- if (!I->hasMetadataOtherThanDebugLoc())
- return;
- auto Track = [](Metadata *ScopeList, auto &Container) {
- const auto *MDScopeList = dyn_cast_or_null<MDNode>(ScopeList);
- if (!MDScopeList || !Container.insert(MDScopeList).second)
- return;
- for (auto &MDOperand : MDScopeList->operands())
- if (auto *MDScope = dyn_cast<MDNode>(MDOperand))
- Container.insert(MDScope);
- };
- Track(I->getMetadata(LLVMContext::MD_alias_scope), UsedAliasScopesAndLists);
- Track(I->getMetadata(LLVMContext::MD_noalias), UsedNoAliasScopesAndLists);
- }
- bool isNoAliasScopeDeclDead(Instruction *Inst) {
- NoAliasScopeDeclInst *Decl = dyn_cast<NoAliasScopeDeclInst>(Inst);
- if (!Decl)
- return false;
- assert(Decl->use_empty() &&
- "llvm.experimental.noalias.scope.decl in use ?");
- const MDNode *MDSL = Decl->getScopeList();
- assert(MDSL->getNumOperands() == 1 &&
- "llvm.experimental.noalias.scope should refer to a single scope");
- auto &MDOperand = MDSL->getOperand(0);
- if (auto *MD = dyn_cast<MDNode>(MDOperand))
- return !UsedAliasScopesAndLists.contains(MD) ||
- !UsedNoAliasScopesAndLists.contains(MD);
-
- return true;
- }
- };
- static bool prepareICWorklistFromFunction(Function &F, const DataLayout &DL,
- const TargetLibraryInfo *TLI,
- InstructionWorklist &ICWorklist) {
- bool MadeIRChange = false;
- SmallPtrSet<BasicBlock *, 32> Visited;
- SmallVector<BasicBlock*, 256> Worklist;
- Worklist.push_back(&F.front());
- SmallVector<Instruction *, 128> InstrsForInstructionWorklist;
- DenseMap<Constant *, Constant *> FoldedConstants;
- AliasScopeTracker SeenAliasScopes;
- do {
- BasicBlock *BB = Worklist.pop_back_val();
-
- if (!Visited.insert(BB).second)
- continue;
- for (Instruction &Inst : llvm::make_early_inc_range(*BB)) {
-
- if (!Inst.use_empty() &&
- (Inst.getNumOperands() == 0 || isa<Constant>(Inst.getOperand(0))))
- if (Constant *C = ConstantFoldInstruction(&Inst, DL, TLI)) {
- LLVM_DEBUG(dbgs() << "IC: ConstFold to: " << *C << " from: " << Inst
- << '\n');
- Inst.replaceAllUsesWith(C);
- ++NumConstProp;
- if (isInstructionTriviallyDead(&Inst, TLI))
- Inst.eraseFromParent();
- MadeIRChange = true;
- continue;
- }
-
- for (Use &U : Inst.operands()) {
- if (!isa<ConstantVector>(U) && !isa<ConstantExpr>(U))
- continue;
- auto *C = cast<Constant>(U);
- Constant *&FoldRes = FoldedConstants[C];
- if (!FoldRes)
- FoldRes = ConstantFoldConstant(C, DL, TLI);
- if (FoldRes != C) {
- LLVM_DEBUG(dbgs() << "IC: ConstFold operand of: " << Inst
- << "\n Old = " << *C
- << "\n New = " << *FoldRes << '\n');
- U = FoldRes;
- MadeIRChange = true;
- }
- }
-
-
-
- if (!Inst.isDebugOrPseudoInst()) {
- InstrsForInstructionWorklist.push_back(&Inst);
- SeenAliasScopes.analyse(&Inst);
- }
- }
-
-
- Instruction *TI = BB->getTerminator();
- if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
- if (BI->isConditional() && isa<ConstantInt>(BI->getCondition())) {
- bool CondVal = cast<ConstantInt>(BI->getCondition())->getZExtValue();
- BasicBlock *ReachableBB = BI->getSuccessor(!CondVal);
- Worklist.push_back(ReachableBB);
- continue;
- }
- } else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
- if (ConstantInt *Cond = dyn_cast<ConstantInt>(SI->getCondition())) {
- Worklist.push_back(SI->findCaseValue(Cond)->getCaseSuccessor());
- continue;
- }
- }
- append_range(Worklist, successors(TI));
- } while (!Worklist.empty());
-
-
-
- for (BasicBlock &BB : F) {
- if (Visited.count(&BB))
- continue;
- unsigned NumDeadInstInBB;
- unsigned NumDeadDbgInstInBB;
- std::tie(NumDeadInstInBB, NumDeadDbgInstInBB) =
- removeAllNonTerminatorAndEHPadInstructions(&BB);
- MadeIRChange |= NumDeadInstInBB + NumDeadDbgInstInBB > 0;
- NumDeadInst += NumDeadInstInBB;
- }
-
-
-
-
-
- ICWorklist.reserve(InstrsForInstructionWorklist.size());
- for (Instruction *Inst : reverse(InstrsForInstructionWorklist)) {
-
-
- if (isInstructionTriviallyDead(Inst, TLI) ||
- SeenAliasScopes.isNoAliasScopeDeclDead(Inst)) {
- ++NumDeadInst;
- LLVM_DEBUG(dbgs() << "IC: DCE: " << *Inst << '\n');
- salvageDebugInfo(*Inst);
- Inst->eraseFromParent();
- MadeIRChange = true;
- continue;
- }
- ICWorklist.push(Inst);
- }
- return MadeIRChange;
- }
- static bool combineInstructionsOverFunction(
- Function &F, InstructionWorklist &Worklist, AliasAnalysis *AA,
- AssumptionCache &AC, TargetLibraryInfo &TLI, TargetTransformInfo &TTI,
- DominatorTree &DT, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI,
- ProfileSummaryInfo *PSI, unsigned MaxIterations, LoopInfo *LI) {
- auto &DL = F.getParent()->getDataLayout();
- MaxIterations = std::min(MaxIterations, LimitMaxIterations.getValue());
-
-
- IRBuilder<TargetFolder, IRBuilderCallbackInserter> Builder(
- F.getContext(), TargetFolder(DL),
- IRBuilderCallbackInserter([&Worklist, &AC](Instruction *I) {
- Worklist.add(I);
- if (auto *Assume = dyn_cast<AssumeInst>(I))
- AC.registerAssumption(Assume);
- }));
-
-
- bool MadeIRChange = false;
- if (ShouldLowerDbgDeclare)
- MadeIRChange = LowerDbgDeclare(F);
-
- unsigned Iteration = 0;
- while (true) {
- ++NumWorklistIterations;
- ++Iteration;
- if (Iteration > InfiniteLoopDetectionThreshold) {
- report_fatal_error(
- "Instruction Combining seems stuck in an infinite loop after " +
- Twine(InfiniteLoopDetectionThreshold) + " iterations.");
- }
- if (Iteration > MaxIterations) {
- LLVM_DEBUG(dbgs() << "\n\n[IC] Iteration limit #" << MaxIterations
- << " on " << F.getName()
- << " reached; stopping before reaching a fixpoint\n");
- break;
- }
- LLVM_DEBUG(dbgs() << "\n\nINSTCOMBINE ITERATION #" << Iteration << " on "
- << F.getName() << "\n");
- MadeIRChange |= prepareICWorklistFromFunction(F, DL, &TLI, Worklist);
- InstCombinerImpl IC(Worklist, Builder, F.hasMinSize(), AA, AC, TLI, TTI, DT,
- ORE, BFI, PSI, DL, LI);
- IC.MaxArraySizeForCombine = MaxArraySize;
- if (!IC.run())
- break;
- MadeIRChange = true;
- }
- return MadeIRChange;
- }
- InstCombinePass::InstCombinePass() : MaxIterations(LimitMaxIterations) {}
- InstCombinePass::InstCombinePass(unsigned MaxIterations)
- : MaxIterations(MaxIterations) {}
- PreservedAnalyses InstCombinePass::run(Function &F,
- FunctionAnalysisManager &AM) {
- auto &AC = AM.getResult<AssumptionAnalysis>(F);
- auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
- auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
- auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
- auto &TTI = AM.getResult<TargetIRAnalysis>(F);
- auto *LI = AM.getCachedResult<LoopAnalysis>(F);
- auto *AA = &AM.getResult<AAManager>(F);
- auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
- ProfileSummaryInfo *PSI =
- MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
- auto *BFI = (PSI && PSI->hasProfileSummary()) ?
- &AM.getResult<BlockFrequencyAnalysis>(F) : nullptr;
- if (!combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, TTI, DT, ORE,
- BFI, PSI, MaxIterations, LI))
-
- return PreservedAnalyses::all();
-
- PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
- return PA;
- }
- void InstructionCombiningPass::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesCFG();
- AU.addRequired<AAResultsWrapperPass>();
- AU.addRequired<AssumptionCacheTracker>();
- AU.addRequired<TargetLibraryInfoWrapperPass>();
- AU.addRequired<TargetTransformInfoWrapperPass>();
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
- AU.addPreserved<DominatorTreeWrapperPass>();
- AU.addPreserved<AAResultsWrapperPass>();
- AU.addPreserved<BasicAAWrapperPass>();
- AU.addPreserved<GlobalsAAWrapperPass>();
- AU.addRequired<ProfileSummaryInfoWrapperPass>();
- LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
- }
- bool InstructionCombiningPass::runOnFunction(Function &F) {
- if (skipFunction(F))
- return false;
-
- auto AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
- auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
- auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
- auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
-
- auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>();
- auto *LI = LIWP ? &LIWP->getLoopInfo() : nullptr;
- ProfileSummaryInfo *PSI =
- &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
- BlockFrequencyInfo *BFI =
- (PSI && PSI->hasProfileSummary()) ?
- &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI() :
- nullptr;
- return combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, TTI, DT, ORE,
- BFI, PSI, MaxIterations, LI);
- }
- char InstructionCombiningPass::ID = 0;
- InstructionCombiningPass::InstructionCombiningPass()
- : FunctionPass(ID), MaxIterations(InstCombineDefaultMaxIterations) {
- initializeInstructionCombiningPassPass(*PassRegistry::getPassRegistry());
- }
- InstructionCombiningPass::InstructionCombiningPass(unsigned MaxIterations)
- : FunctionPass(ID), MaxIterations(MaxIterations) {
- initializeInstructionCombiningPassPass(*PassRegistry::getPassRegistry());
- }
- INITIALIZE_PASS_BEGIN(InstructionCombiningPass, "instcombine",
- "Combine redundant instructions", false, false)
- INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
- INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
- INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
- INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
- INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
- INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
- INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
- INITIALIZE_PASS_DEPENDENCY(LazyBlockFrequencyInfoPass)
- INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
- INITIALIZE_PASS_END(InstructionCombiningPass, "instcombine",
- "Combine redundant instructions", false, false)
- void llvm::initializeInstCombine(PassRegistry &Registry) {
- initializeInstructionCombiningPassPass(Registry);
- }
- void LLVMInitializeInstCombine(LLVMPassRegistryRef R) {
- initializeInstructionCombiningPassPass(*unwrap(R));
- }
- FunctionPass *llvm::createInstructionCombiningPass() {
- return new InstructionCombiningPass();
- }
- FunctionPass *llvm::createInstructionCombiningPass(unsigned MaxIterations) {
- return new InstructionCombiningPass(MaxIterations);
- }
- void LLVMAddInstructionCombiningPass(LLVMPassManagerRef PM) {
- unwrap(PM)->add(createInstructionCombiningPass());
- }
|