Index: llvm/lib/Transforms/Scalar/LoopFuse.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopFuse.cpp +++ llvm/lib/Transforms/Scalar/LoopFuse.cpp @@ -415,9 +415,29 @@ return true; } - // If LHS does not dominate RHS and RHS does not dominate LHS then there is - // no dominance relationship between the two FusionCandidates. Thus, they - // should not be in the same set together. + // If two FusionCandidates are in same level of dominator tree then, + // they will not be dominates each other. But may be control flow + // equivalent. To sort those FusionCandidates nonStrictlyPostDominate is + // needed. + bool bWrongOrder = + nonStrictlyPostDominate(LHSEntryBlock, RHSEntryBlock, DT, LHS.PDT); + bool bRightOrder = + nonStrictlyPostDominate(RHSEntryBlock, LHSEntryBlock, DT, LHS.PDT); + if (bWrongOrder && bRightOrder) { + DomTreeNode *LNode = LHS.PDT->getNode(LHSEntryBlock); + DomTreeNode *RNode = LHS.PDT->getNode(RHSEntryBlock); + if (LNode->getLevel() > RNode->getLevel()) + return true; + else + return false; + } else if (bWrongOrder) + return false; + else if (bRightOrder) + return true; + + // If LHS does not non-strict Postdominate RHS and RHS does not non-strict + // Postdominate LHS then, there is no dominance relationship between the + // two FusionCandidates. Thus, they should not be in the same set together. llvm_unreachable( "No dominance relationship between these fusion candidates!"); } Index: llvm/test/Transforms/LoopFusion/undominated_loops.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopFusion/undominated_loops.ll @@ -0,0 +1,26 @@ +; RUN: opt -S -passes=loop-simplify,newgvn,loop-fusion -pass-remarks-analysis=loop-fusion -disable-output < %s 2>&1 | FileCheck %s + +; CHECK: remark: :0:0: [function_0]: Loop is not a candidate for fusion: Loop has unknown trip count + +define void @function_0() { +entry_1: + br i1 false, label %bb_2, label %bb_3 + +bb_2: ; preds = %bb_7, %bb_5, %bb_2, %entry_1 + br i1 false, label %bb_2, label %bb_5 + +bb_3: ; preds = %bb_3, %entry_1 + br i1 false, label %bb_3, label %bb_4 + +bb_4: ; preds = %bb_3 + br label %bb_6 + +bb_5: ; preds = %bb_2 + br i1 undef, label %bb_2, label %bb_7 + +bb_6: ; preds = %bb_7, %bb_6, %bb_4 + br i1 undef, label %bb_7, label %bb_6 + +bb_7: ; preds = %bb_6, %bb_5 + br i1 undef, label %bb_2, label %bb_6 +}