From eda3c93486ca113f63ccf8f28ca9c0ea90c09386 Mon Sep 17 00:00:00 2001 From: Mengxuan Cai Date: Mon, 31 Oct 2022 11:45:44 -0400 Subject: [PATCH] [LoopFuse] Ensure loops are in loop simplified form under new PM Loop Fusion (Function Pass) requires loops in simplified form. With legacy-pm, loop-simplify pass is added as a dependency for loop-fusion. But the new pass manager does not always ensure this format. This patch tries to invoke simplifyLoop() on loops that are not in simplified form only for new PM. Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D136781 --- llvm/lib/Transforms/Scalar/LoopFuse.cpp | 15 +++++++++- .../LoopFusion/ensure_loop_simplify_form.ll | 35 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/LoopFusion/ensure_loop_simplify_form.ll diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp index 5157f05..9d70f89 100644 --- 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 @@ PreservedAnalyses LoopFusePass::run(Function &F, FunctionAnalysisManager &AM) { 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 index 0000000..c80b08e --- /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 +} -- 2.7.4