@@ -60,7 +60,7 @@ namespace {
6060
6161constexpr unsigned ThreadsPerBlock = 256 ;
6262constexpr unsigned InputCount = 256 ;
63- constexpr unsigned MaxIRCFGBlocks = 512 ;
63+ constexpr unsigned MaxIRCFGBlocks = 768 ;
6464
6565constexpr StringRef DataLayout =
6666 " e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-"
@@ -1960,13 +1960,13 @@ struct CFGFragment {
19601960unsigned chooseCFGDepth (const Function &F, unsigned HardMax,
19611961 std::minstd_rand &Gen) {
19621962 unsigned MaxDepth = HardMax;
1963- if (F.size () >= MaxIRCFGBlocks - 64 )
1963+ if (F.size () >= MaxIRCFGBlocks - 96 )
19641964 MaxDepth = 1 ;
1965- else if (F.size () >= 384 )
1965+ else if (F.size () >= 576 )
19661966 MaxDepth = std::min (MaxDepth, 2u );
1967- else if (F.size () >= 192 )
1967+ else if (F.size () >= 384 )
19681968 MaxDepth = std::min (MaxDepth, 3u );
1969- else if (F.size () >= 96 )
1969+ else if (F.size () >= 192 )
19701970 MaxDepth = std::min (MaxDepth, 4u );
19711971
19721972 unsigned Depth = 1 ;
@@ -2068,6 +2068,80 @@ CFGFragment emitRandomNestedSwitch(IRBuilder<NoFolder> &B, Module &M,
20682068 return {Phi, Join};
20692069}
20702070
2071+ CFGFragment emitRandomNestedCountedLoop (IRBuilder<NoFolder> &B, Module &M,
2072+ BasicBlock *InsertBefore,
2073+ Value *Current, Value *Other,
2074+ unsigned Depth,
2075+ std::minstd_rand &Gen) {
2076+ LLVMContext &Ctx = M.getContext ();
2077+ Type *I32 = Type::getInt32Ty (Ctx);
2078+ Function *F = B.GetInsertBlock ()->getParent ();
2079+ BasicBlock *Preheader = B.GetInsertBlock ();
2080+ BasicBlock *Header =
2081+ BasicBlock::Create (Ctx, " fuzz.nested.loop.header" , F, InsertBefore);
2082+ BasicBlock *Body =
2083+ BasicBlock::Create (Ctx, " fuzz.nested.loop.body" , F, InsertBefore);
2084+ BasicBlock *Exit =
2085+ BasicBlock::Create (Ctx, " fuzz.nested.loop.exit" , F, InsertBefore);
2086+ bool UseEarlyExit = (Gen () % 5 ) == 0 ;
2087+
2088+ Value *TripCount = nullptr ;
2089+ if ((Gen () % 2 ) == 0 ) {
2090+ TripCount = ci32 (Ctx, 1 + (Gen () % 4 ));
2091+ } else {
2092+ Value *TripSeed =
2093+ (Gen () % 2 ) == 0 ? Current : chooseCFGValue (Ctx, Other, Gen);
2094+ Value *Masked =
2095+ B.CreateAnd (TripSeed, ci32 (Ctx, 3 ), " fuzz.loop.trip.inner.mask" );
2096+ TripCount = B.CreateAdd (Masked, ci32 (Ctx, 1 ), " fuzz.loop.trip.inner" );
2097+ }
2098+ B.CreateBr (Header);
2099+
2100+ IRBuilder<NoFolder> HeaderB (Header);
2101+ PHINode *Index = HeaderB.CreatePHI (I32 , 2 , " fuzz.loop.iv.inner" );
2102+ PHINode *Acc = HeaderB.CreatePHI (I32 , 2 , " fuzz.loop.acc.inner" );
2103+ Index->addIncoming (ci32 (Ctx, 0 ), Preheader);
2104+ Acc->addIncoming (Current, Preheader);
2105+ Value *Cond = HeaderB.CreateICmpULT (Index, TripCount,
2106+ " fuzz.loop.cond.inner" );
2107+ HeaderB.CreateCondBr (Cond, Body, Exit);
2108+
2109+ IRBuilder<NoFolder> BodyB (Body);
2110+ CFGFragment BodyFrag =
2111+ emitRandomCFGSubgraph (BodyB, M, Exit, Acc, Other, Depth - 1 , Gen);
2112+
2113+ Value *NextAcc = BodyFrag.Result ;
2114+ Value *ExitResult = Acc;
2115+ BasicBlock *Backedge = BodyFrag.Tail ;
2116+ if (UseEarlyExit) {
2117+ IRBuilder<NoFolder> BreakB (BodyFrag.Tail );
2118+ Value *BreakCond =
2119+ BreakB.CreateICmp (randomICmpPredicate (Gen), NextAcc,
2120+ chooseCFGValue (Ctx, Other, Gen),
2121+ " fuzz.loop.break.inner" );
2122+ Backedge =
2123+ BasicBlock::Create (Ctx, " fuzz.nested.loop.continue" , F, Exit);
2124+ BreakB.CreateCondBr (BreakCond, Exit, Backedge);
2125+
2126+ PHINode *ExitPhi =
2127+ PHINode::Create (I32 , 2 , " fuzz.loop.exit.value.inner" , Exit->begin ());
2128+ ExitPhi->addIncoming (Acc, Header);
2129+ ExitPhi->addIncoming (NextAcc, BodyFrag.Tail );
2130+ ExitResult = ExitPhi;
2131+ }
2132+
2133+ IRBuilder<NoFolder> BackedgeB (Backedge);
2134+ if ((Gen () % 2 ) == 0 )
2135+ NextAcc = BackedgeB.CreateXor (NextAcc, Index, " fuzz.loop.acc.inner.mix" );
2136+ Value *NextIndex =
2137+ BackedgeB.CreateAdd (Index, ci32 (Ctx, 1 ), " fuzz.loop.next.inner" );
2138+ BackedgeB.CreateBr (Header);
2139+ Index->addIncoming (NextIndex, Backedge);
2140+ Acc->addIncoming (NextAcc, Backedge);
2141+
2142+ return {ExitResult, Exit};
2143+ }
2144+
20712145CFGFragment emitRandomCFGSubgraph (IRBuilder<NoFolder> &B, Module &M,
20722146 BasicBlock *InsertBefore, Value *Current,
20732147 Value *Other, unsigned Depth,
@@ -2078,11 +2152,17 @@ CFGFragment emitRandomCFGSubgraph(IRBuilder<NoFolder> &B, Module &M,
20782152 return {Linear, B.GetInsertBlock ()};
20792153
20802154 Value *NestedOther = chooseCFGValue (M.getContext (), Other, Gen);
2081- if ((Gen () % 4 ) == 0 )
2155+ switch (Gen () % 5 ) {
2156+ case 0 :
20822157 return emitRandomNestedSwitch (B, M, InsertBefore, Linear, NestedOther,
20832158 Depth, Gen);
2084- return emitRandomNestedDiamond (B, M, InsertBefore, Linear, NestedOther,
2085- Depth, Gen);
2159+ case 1 :
2160+ return emitRandomNestedCountedLoop (B, M, InsertBefore, Linear, NestedOther,
2161+ Depth, Gen);
2162+ default :
2163+ return emitRandomNestedDiamond (B, M, InsertBefore, Linear, NestedOther,
2164+ Depth, Gen);
2165+ }
20862166}
20872167
20882168void mutateIRAddDiamond (Module &M, std::minstd_rand &Gen) {
@@ -2109,13 +2189,13 @@ void mutateIRAddDiamond(Module &M, std::minstd_rand &Gen) {
21092189
21102190 IRBuilder<NoFolder> ThenB (Then);
21112191 CFGFragment ThenFrag = emitRandomCFGSubgraph (
2112- ThenB, M, Join, Current, Other, chooseCFGDepth (*F, 6 , Gen), Gen);
2192+ ThenB, M, Join, Current, Other, chooseCFGDepth (*F, 8 , Gen), Gen);
21132193 IRBuilder<NoFolder> ThenTailB (ThenFrag.Tail );
21142194 ThenTailB.CreateBr (Join);
21152195
21162196 IRBuilder<NoFolder> ElseB (Else);
21172197 CFGFragment ElseFrag = emitRandomCFGSubgraph (
2118- ElseB, M, Join, Current, Other, chooseCFGDepth (*F, 6 , Gen), Gen);
2198+ ElseB, M, Join, Current, Other, chooseCFGDepth (*F, 8 , Gen), Gen);
21192199 IRBuilder<NoFolder> ElseTailB (ElseFrag.Tail );
21202200 ElseTailB.CreateBr (Join);
21212201
@@ -2164,15 +2244,15 @@ void mutateIRAddSwitch(Module &M, std::minstd_rand &Gen) {
21642244 Value *CaseOther =
21652245 (I % 2 ) == 0 ? Other : ci32 (Ctx, randomInteresting64 (Gen));
21662246 CFGFragment CaseFrag = emitRandomCFGSubgraph (
2167- CaseB, M, Join, Current, CaseOther, chooseCFGDepth (*F, 5 , Gen), Gen);
2247+ CaseB, M, Join, Current, CaseOther, chooseCFGDepth (*F, 7 , Gen), Gen);
21682248 IRBuilder<NoFolder> CaseTailB (CaseFrag.Tail );
21692249 CaseTailB.CreateBr (Join);
21702250 Phi->addIncoming (CaseFrag.Result , CaseFrag.Tail );
21712251 }
21722252
21732253 IRBuilder<NoFolder> DefaultB (Default);
21742254 CFGFragment DefaultFrag = emitRandomCFGSubgraph (
2175- DefaultB, M, Join, Current, Other, chooseCFGDepth (*F, 5 , Gen), Gen);
2255+ DefaultB, M, Join, Current, Other, chooseCFGDepth (*F, 7 , Gen), Gen);
21762256 IRBuilder<NoFolder> DefaultTailB (DefaultFrag.Tail );
21772257 DefaultTailB.CreateBr (Join);
21782258 Phi->addIncoming (DefaultFrag.Result , DefaultFrag.Tail );
@@ -2353,7 +2433,7 @@ void mutateIRModule(Module &M, std::minstd_rand &Gen) {
23532433 while (NumMutations < 24 && (Gen () % 4 ) == 0 )
23542434 ++NumMutations;
23552435 for (unsigned I = 0 ; I < NumMutations; ++I) {
2356- switch (Gen () % 15 ) {
2436+ switch (Gen () % 17 ) {
23572437 case 0 :
23582438 case 1 :
23592439 case 2 :
@@ -2362,19 +2442,22 @@ void mutateIRModule(Module &M, std::minstd_rand &Gen) {
23622442 case 3 :
23632443 case 4 :
23642444 case 5 :
2445+ case 6 :
23652446 mutateIRAddDiamond (M, Gen);
23662447 break ;
2367- case 6 :
23682448 case 7 :
23692449 case 8 :
2370- mutateIRAddSwitch (M, Gen);
2371- break ;
23722450 case 9 :
23732451 case 10 :
2374- mutateIRAddCountedLoop (M, Gen);
2452+ mutateIRAddSwitch (M, Gen);
23752453 break ;
23762454 case 11 :
23772455 case 12 :
2456+ case 13 :
2457+ mutateIRAddCountedLoop (M, Gen);
2458+ break ;
2459+ case 14 :
2460+ case 15 :
23782461 mutateIRModifyConstant (M, Gen);
23792462 break ;
23802463 default :
0 commit comments