@@ -2716,6 +2716,14 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
2716
2716
if (isa<ConstantInt>(IfCond))
2717
2717
return false ;
2718
2718
2719
+ BasicBlock *DomBlock = DomBI->getParent ();
2720
+ SmallVector<BasicBlock *, 2 > IfBlocks;
2721
+ llvm::copy_if (
2722
+ PN->blocks (), std::back_inserter (IfBlocks), [](BasicBlock *IfBlock) {
2723
+ return cast<BranchInst>(IfBlock->getTerminator ())->isUnconditional ();
2724
+ });
2725
+ assert (!IfBlocks.empty () && " Will have at least one block to speculate." );
2726
+
2719
2727
// Don't try to fold an unreachable block. For example, the phi node itself
2720
2728
// can't be the candidate if-condition for a select that we want to form.
2721
2729
if (auto *IfCondPhiInst = dyn_cast<PHINode>(IfCond))
@@ -2794,38 +2802,19 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
2794
2802
// in the predecessor blocks can be promoted as well. If not, we won't be able
2795
2803
// to get rid of the control flow, so it's not worth promoting to select
2796
2804
// instructions.
2797
- BasicBlock *DomBlock = DomBI->getParent ();
2798
- BasicBlock *IfBlock1 = PN->getIncomingBlock (0 );
2799
- BasicBlock *IfBlock2 = PN->getIncomingBlock (1 );
2800
- if (cast<BranchInst>(IfBlock1->getTerminator ())->isConditional ()) {
2801
- IfBlock1 = nullptr ;
2802
- } else {
2803
- for (BasicBlock::iterator I = IfBlock1->begin (); !I->isTerminator (); ++I)
2804
- if (!AggressiveInsts.count (&*I) && !isa<DbgInfoIntrinsic>(I) &&
2805
- !isa<PseudoProbeInst>(I)) {
2806
- // This is not an aggressive instruction that we can promote.
2807
- // Because of this, we won't be able to get rid of the control flow, so
2808
- // the xform is not worth it.
2809
- return Changed;
2810
- }
2811
- }
2812
-
2813
- if (cast<BranchInst>(IfBlock2->getTerminator ())->isConditional ()) {
2814
- IfBlock2 = nullptr ;
2815
- } else {
2816
- for (BasicBlock::iterator I = IfBlock2->begin (); !I->isTerminator (); ++I)
2805
+ for (BasicBlock *IfBlock : IfBlocks)
2806
+ for (BasicBlock::iterator I = IfBlock->begin (); !I->isTerminator (); ++I)
2817
2807
if (!AggressiveInsts.count (&*I) && !isa<DbgInfoIntrinsic>(I) &&
2818
2808
!isa<PseudoProbeInst>(I)) {
2819
2809
// This is not an aggressive instruction that we can promote.
2820
2810
// Because of this, we won't be able to get rid of the control flow, so
2821
2811
// the xform is not worth it.
2822
2812
return Changed;
2823
2813
}
2824
- }
2825
2814
2826
2815
// If either of the blocks has it's address taken, we can't do this fold.
2827
- if ((IfBlock1 && IfBlock1-> hasAddressTaken ()) ||
2828
- (IfBlock2 && IfBlock2 ->hasAddressTaken ()))
2816
+ if (any_of (IfBlocks,
2817
+ [](BasicBlock *IfBlock) { return IfBlock ->hasAddressTaken (); } ))
2829
2818
return Changed;
2830
2819
2831
2820
LLVM_DEBUG (dbgs () << " FOUND IF CONDITION! " << *IfCond
@@ -2837,10 +2826,8 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
2837
2826
2838
2827
// Move all 'aggressive' instructions, which are defined in the
2839
2828
// conditional parts of the if's up to the dominating block.
2840
- if (IfBlock1)
2841
- hoistAllInstructionsInto (DomBlock, DomBI, IfBlock1);
2842
- if (IfBlock2)
2843
- hoistAllInstructionsInto (DomBlock, DomBI, IfBlock2);
2829
+ for (BasicBlock *IfBlock : IfBlocks)
2830
+ hoistAllInstructionsInto (DomBlock, DomBI, IfBlock);
2844
2831
2845
2832
IRBuilder<NoFolder> Builder (DomBI);
2846
2833
// Propagate fast-math-flags from phi nodes to replacement selects.
@@ -2850,16 +2837,16 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
2850
2837
Builder.setFastMathFlags (PN->getFastMathFlags ());
2851
2838
2852
2839
// Change the PHI node into a select instruction.
2853
- Value *TrueVal = PN->getIncomingValue (PN-> getIncomingBlock ( 0 ) == IfFalse );
2854
- Value *FalseVal = PN->getIncomingValue (PN-> getIncomingBlock ( 0 ) == IfTrue );
2840
+ Value *TrueVal = PN->getIncomingValueForBlock (IfTrue );
2841
+ Value *FalseVal = PN->getIncomingValueForBlock (IfFalse );
2855
2842
2856
2843
Value *Sel = Builder.CreateSelect (IfCond, TrueVal, FalseVal, " " , DomBI);
2857
2844
PN->replaceAllUsesWith (Sel);
2858
2845
Sel->takeName (PN);
2859
2846
PN->eraseFromParent ();
2860
2847
}
2861
2848
2862
- // At this point, IfBlock1 and IfBlock2 are both empty, so our if statement
2849
+ // At this point, all IfBlocks are empty, so our if statement
2863
2850
// has been flattened. Change DomBlock to jump directly to our new block to
2864
2851
// avoid other simplifycfg's kicking in on the diamond.
2865
2852
Builder.CreateBr (BB);
0 commit comments