diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp --- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp +++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp @@ -67,6 +67,7 @@ #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/CodeMoverUtils.h" #include "llvm/Transforms/Utils/LoopPeel.h" +#include "llvm/Transforms/Utils/LoopSimplify.h" using namespace llvm; @@ -2085,8 +2086,20 @@ const TargetTransformInfo &TTI = AM.getResult(F); const DataLayout &DL = F.getParent()->getDataLayout(); + // Ensure loops are in simplifed form which is a pre-requisite for loop fusion + // pass. Added only for new PM since the legacy PM has already added + // LoopSimplify pass as a dependency. + bool Changed = false; + for (auto &L : LI) { + if (!L->isLoopSimplifyForm()) + Changed |= simplifyLoop(L, &DT, &LI, &SE, &AC, nullptr, + false /* PreserveLCSSA */); + } + if (Changed) + PDT.recalculate(F); + LoopFuser LF(LI, DT, DI, SE, PDT, ORE, DL, AC, TTI); - bool Changed = LF.fuseLoops(F); + Changed |= LF.fuseLoops(F); if (!Changed) return PreservedAnalyses::all(); diff --git a/llvm/test/Transforms/LoopFusion/ensure_loop_simplify_form.ll b/llvm/test/Transforms/LoopFusion/ensure_loop_simplify_form.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/LoopFusion/ensure_loop_simplify_form.ll @@ -0,0 +1,35 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=loop-fusion -S | FileCheck %s + +define void @v_5_0(i32* %dummy) { +; CHECK-LABEL: @v_5_0( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.cond.cleanup: +; CHECK-NEXT: br i1 true, label [[FOR_BODY6_PREHEADER:%.*]], label [[FOR_COND_CLEANUP5:%.*]] +; CHECK: for.body6.preheader: +; CHECK-NEXT: br label [[FOR_BODY6:%.*]] +; CHECK: for.body: +; CHECK-NEXT: br i1 false, label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]] +; CHECK: for.cond.cleanup5: +; CHECK-NEXT: ret void +; CHECK: for.body6: +; CHECK-NEXT: [[V_LOOP_2_0_V_LOOP_2_0_V_LOOP_2_0_18:%.*]] = load volatile i32, i32* [[DUMMY:%.*]], align 1 +; CHECK-NEXT: br label [[FOR_BODY6]] +; +entry: + br label %for.body + +for.cond.cleanup: ; preds = %for.body + br i1 true, label %for.body6, label %for.cond.cleanup5 + +for.body: ; preds = %for.body, %entry + br i1 false, label %for.cond.cleanup, label %for.body + +for.cond.cleanup5: ; preds = %for.cond.cleanup + ret void + +for.body6: ; preds = %for.body6, %for.cond.cleanup + %v_loop_2.0.v_loop_2.0.v_loop_2.0.18 = load volatile i32, i32* %dummy, align 1 + br label %for.body6 +}