@@ -2744,7 +2744,7 @@ bool GVNPass::processInstruction(Instruction *I) {
27442744 return Changed;
27452745 }
27462746 if (SelectInst *Select = dyn_cast<SelectInst>(I)) {
2747- if (optimizeMinMaxFindingSelectPattern (Select))
2747+ if (recognizeMinFindingSelectPattern (Select))
27482748 return true ;
27492749 }
27502750
@@ -3334,19 +3334,99 @@ void GVNPass::assignValNumForDeadCode() {
33343334 }
33353335}
33363336
3337- bool GVNPass::optimizeMinMaxFindingSelectPattern (SelectInst *Select) {
3337+ bool GVNPass::transformMinFindingSelectPattern (Loop *L, BasicBlock *Preheader,
3338+ BasicBlock *BB, Value *LHS,
3339+ Value *RHS, CmpInst *Comparison,
3340+ SelectInst *Select,
3341+ Value *BasePtr, Value *IndexVal,
3342+ Value *OffsetVal) {
3343+ // Hoist the chain of operations for the second load to preheader.
3344+ // %min.idx.ext = sext i32 %min.idx to i64
3345+ // %ptr.float.min = getelementptr float, ptr %0, i64 %min.idx.ext
3346+ // %ptr.second.load = getelementptr i8, ptr %ptr.float.min, i64 -4
3347+ // %val.current.min = load float, ptr %ptr.second.load, align 4
3348+ IRBuilder<> Builder (Preheader->getTerminator ());
3349+
3350+ PHINode *Phi = dyn_cast<PHINode>(IndexVal);
3351+ if (!Phi) {
3352+ LLVM_DEBUG (dbgs () << " GVN: IndexVal is not a PHI node\n " );
3353+ return false ;
3354+ }
3355+
3356+ Value *InitialMinIndex = Phi->getIncomingValueForBlock (Preheader);
3357+
3358+ // Insert PHI node at the top of this block.
3359+ // This PHI node will be used to memoize the current minimum value so far.
3360+ PHINode *KnownMinPhi =
3361+ PHINode::Create (Builder.getFloatTy (), 2 , " known_min" , BB->begin ());
3362+
3363+ // Hoist the load and build the necessary operations.
3364+ // 1. hoist_0 = sext i32 to i64
3365+ Value *HoistedSExt =
3366+ Builder.CreateSExt (InitialMinIndex, Builder.getInt64Ty (), " hoist_sext" );
3367+
3368+ // 2. hoist_gep1 = getelementptr float, ptr BasePtr, i64 HoistedSExt
3369+ Value *HoistedGEP1 = Builder.CreateGEP (Builder.getFloatTy (), BasePtr,
3370+ HoistedSExt, " hoist_gep1" );
3371+
3372+ // 3. hoist_gep2 = getelementptr i8, ptr HoistedGEP1, i64 OffsetVal
3373+ Value *HoistedGEP2 = Builder.CreateGEP (Builder.getInt8Ty (), HoistedGEP1,
3374+ OffsetVal, " hoist_gep2" );
3375+
3376+ // 4. hoisted_load = load float, ptr HoistedGEP2
3377+ LoadInst *NewLoad =
3378+ Builder.CreateLoad (Builder.getFloatTy (), HoistedGEP2, " hoisted_load" );
3379+
3380+ // Let the new load now take the place of the old load.
3381+ RHS->replaceAllUsesWith (NewLoad);
3382+ dyn_cast<LoadInst>(RHS)->eraseFromParent ();
3383+
3384+ // Comparison should now compare the current value and the newly inserted
3385+ // PHI node.
3386+ Comparison->setOperand (1 , KnownMinPhi);
3387+
3388+ // Create new select instruction for selecting the minimum value.
3389+ IRBuilder<> SelectBuilder (BB->getTerminator ());
3390+ SelectInst *CurrentMinSelect = dyn_cast<SelectInst>(
3391+ SelectBuilder.CreateSelect (Comparison, LHS, KnownMinPhi, " current_min" ));
3392+
3393+ // Populate the newly created PHI node
3394+ // with (hoisted) NewLoad from the preheader and CurrentMinSelect.
3395+ KnownMinPhi->addIncoming (NewLoad, Preheader);
3396+ KnownMinPhi->addIncoming (CurrentMinSelect, BB);
3397+ LLVM_DEBUG (dbgs () << " Transformed the code\n " );
3398+ return true ;
3399+ }
3400+
3401+ bool GVNPass::recognizeMinFindingSelectPattern (SelectInst *Select) {
3402+ Value *BasePtr = nullptr , *IndexVal = nullptr , *OffsetVal = nullptr ;
33383403 LLVM_DEBUG (
33393404 dbgs ()
3340- << " GVN: Analyzing select instruction for minimum finding pattern\n " );
3405+ << " GVN: Analyzing select instruction for minimum finding pattern. \n " );
33413406 LLVM_DEBUG (dbgs () << " GVN: Select: " << *Select << " \n " );
3407+ BasicBlock *BB = Select->getParent ();
3408+
3409+ // If the block is not in a loop, bail out.
3410+ Loop *L = LI->getLoopFor (BB);
3411+ if (!L) {
3412+ LLVM_DEBUG (dbgs () << " GVN: Could not find loop.\n " );
3413+ return false ;
3414+ }
3415+
3416+ // If preheader of the loop is not found, bail out.
3417+ BasicBlock *Preheader = L->getLoopPreheader ();
3418+ if (!Preheader) {
3419+ LLVM_DEBUG (dbgs () << " GVN: Could not find loop preheader.\n " );
3420+ return false ;
3421+ }
33423422 Value *Condition = Select->getCondition ();
33433423 CmpInst *Comparison = dyn_cast<CmpInst>(Condition);
33443424 if (!Comparison) {
3345- LLVM_DEBUG (dbgs () << " GVN: Condition is not a comparison\n " );
3425+ LLVM_DEBUG (dbgs () << " GVN: Condition is not a comparison. \n " );
33463426 return false ;
33473427 }
33483428
3349- // Check if this is ULT comparison.
3429+ // Check if this is less-than comparison.
33503430 CmpInst::Predicate Pred = Comparison->getPredicate ();
33513431 if (Pred != CmpInst::ICMP_SLT && Pred != CmpInst::ICMP_ULT &&
33523432 Pred != CmpInst::FCMP_OLT && Pred != CmpInst::FCMP_ULT) {
@@ -3359,99 +3439,24 @@ bool GVNPass::optimizeMinMaxFindingSelectPattern(SelectInst *Select) {
33593439 Value *LHS = Comparison->getOperand (0 );
33603440 Value *RHS = Comparison->getOperand (1 );
33613441 if (!isa<LoadInst>(LHS) || !isa<LoadInst>(RHS)) {
3362- LLVM_DEBUG (dbgs () << " GVN: Not both operands are loads\n " );
3442+ LLVM_DEBUG (dbgs () << " GVN: Not both operands are loads. \n " );
33633443 return false ;
33643444 }
33653445
3366- LLVM_DEBUG (dbgs () << " GVN: Found minimum finding pattern in Block: "
3367- << Select->getParent ()->getName () << " \n " );
3368-
3369- // Transform the pattern.
3370- // Hoist the chain of operations for the second load to preheader.
3371- // Get predecessor of the block containing the select instruction.
3372- BasicBlock *BB = Select->getParent ();
3373-
3374- // Get preheader of the loop.
3375- Loop *L = LI->getLoopFor (BB);
3376- if (!L) {
3377- LLVM_DEBUG (dbgs () << " GVN: Could not find loop\n " );
3378- return false ;
3379- }
3380- BasicBlock *Preheader = L->getLoopPreheader ();
3381- if (!Preheader) {
3382- LLVM_DEBUG (dbgs () << " GVN: Could not find loop preheader\n " );
3446+ if (!match (RHS,
3447+ m_Load (m_GEP (m_GEP (m_Value (BasePtr), m_SExt (m_Value (IndexVal))),
3448+ m_Value (OffsetVal))))) {
3449+ LLVM_DEBUG (dbgs () << " GVN: Not a required load pattern.\n " );
33833450 return false ;
33843451 }
3452+ LLVM_DEBUG (dbgs () << " GVN: Found minimum finding pattern in Block: "
3453+ << Select->getParent ()->getName () << " .\n " );
33853454
3386- // Hoist the chain of operations for the second load to preheader.
3387- // %90 = sext i32 %.05.i to i64
3388- // %91 = getelementptr float, ptr %0, i64 %90 ; %0 + (sext i32 %85 to i64)*4
3389- // %92 = getelementptr i8, ptr %91, i64 -4 ; %0 + (sext i32 %85 to i64)*4 - 4
3390- // %93 = load float, ptr %92, align 4
3391-
3392- Value *BasePtr = nullptr , *IndexVal = nullptr , *OffsetVal = nullptr ;
3393- IRBuilder<> Builder (Preheader->getTerminator ());
3394- if (match (RHS,
3395- m_Load (m_GEP (m_GEP (m_Value (BasePtr), m_SExt (m_Value (IndexVal))),
3396- m_Value (OffsetVal))))) {
3397- LLVM_DEBUG (dbgs () << " GVN: Found pattern: " << *RHS << " \n " );
3398- LLVM_DEBUG (dbgs () << " GVN: Found pattern: " << " \n " );
3399-
3400- PHINode *Phi = dyn_cast<PHINode>(IndexVal);
3401- if (!Phi) {
3402- LLVM_DEBUG (dbgs () << " GVN: IndexVal is not a PHI node\n " );
3403- return false ;
3404- }
3405- Value *InitialMinIndex = Phi->getIncomingValueForBlock (Preheader);
3406-
3407- // Insert PHI node at the top of this block.
3408- PHINode *KnownMinPhi =
3409- PHINode::Create (Builder.getFloatTy (), 2 , " known_min" , BB->begin ());
3410-
3411- // Build the GEP chain in the preheader.
3412- // 1. hoist_0 = sext i32 to i64
3413- Value *HoistedSExt =
3414- Builder.CreateSExt (InitialMinIndex, Builder.getInt64Ty (), " hoist_sext" );
3415-
3416- // 2. hoist_gep1 = getelementptr float, ptr BasePtr, i64 HoistedSExt
3417- Value *HoistedGEP1 = Builder.CreateGEP (Builder.getFloatTy (), BasePtr,
3418- HoistedSExt, " hoist_gep1" );
3419-
3420- // 3. hoist_gep2 = getelementptr i8, ptr HoistedGEP1, i64 OffsetVal
3421- Value *HoistedGEP2 = Builder.CreateGEP (Builder.getInt8Ty (), HoistedGEP1,
3422- OffsetVal, " hoist_gep2" );
3423-
3424- // 4. hoisted_load = load float, ptr HoistedGEP2
3425- LoadInst *NewLoad =
3426- Builder.CreateLoad (Builder.getFloatTy (), HoistedGEP2, " hoisted_load" );
3427-
3428- // Replace all uses of load with new load.
3429- RHS->replaceAllUsesWith (NewLoad);
3430- dyn_cast<LoadInst>(RHS)->eraseFromParent ();
3431-
3432- // Replace second operand of comparison with KnownMinPhi.
3433- Comparison->setOperand (1 , KnownMinPhi);
3434-
3435- // Create new select instruction for selecting the minimum value.
3436- IRBuilder<> SelectBuilder (BB->getTerminator ());
3437- SelectInst *CurrentMinSelect =
3438- dyn_cast<SelectInst>(SelectBuilder.CreateSelect (
3439- Comparison, LHS, KnownMinPhi, " current_min" ));
3440-
3441- // Populate PHI node.
3442- KnownMinPhi->addIncoming (NewLoad, Preheader);
3443- KnownMinPhi->addIncoming (CurrentMinSelect, BB);
3444- LLVM_DEBUG (dbgs () << " Transformed the code\n " );
3445- return true ;
3446- } else {
3447- LLVM_DEBUG (dbgs () << " GVN: Could not find pattern: " << *RHS << " \n " );
3448- LLVM_DEBUG (dbgs () << " GVN: Could not find pattern: " << " \n " );
3449- return false ;
3450- }
3451- return false ;
3455+ return transformMinFindingSelectPattern (L, Preheader, BB, LHS, RHS,
3456+ Comparison, Select, BasePtr, IndexVal,
3457+ OffsetVal);
34523458}
34533459
3454-
34553460class llvm ::gvn::GVNLegacyPass : public FunctionPass {
34563461public:
34573462 static char ID; // Pass identification, replacement for typeid.
0 commit comments