From aca7441c7ae2c8a0518764265ef6a08449165ced Mon Sep 17 00:00:00 2001 From: luxufan Date: Tue, 3 Jan 2023 23:05:18 +0800 Subject: [PATCH] [LoopFusion] Exit early if one of fusion candidate has guarded branch but the another has not Fixes: https://github.com/llvm/llvm-project/issues/59024 Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D138269 --- llvm/lib/Transforms/Scalar/LoopFuse.cpp | 7 ++++--- llvm/test/Transforms/LoopFusion/guarded.ll | 30 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp index 77323f1..34bb165 100644 --- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp +++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp @@ -896,9 +896,10 @@ private: continue; } - if (!FC0->GuardBranch && FC1->GuardBranch) { - LLVM_DEBUG(dbgs() << "The second candidate is guarded while the " - "first one is not. Not fusing.\n"); + if ((!FC0->GuardBranch && FC1->GuardBranch) || + (FC0->GuardBranch && !FC1->GuardBranch)) { + LLVM_DEBUG(dbgs() << "The one of candidate is guarded while the " + "another one is not. Not fusing.\n"); reportLoopFusion( *FC0, *FC1, OnlySecondCandidateIsGuarded); continue; diff --git a/llvm/test/Transforms/LoopFusion/guarded.ll b/llvm/test/Transforms/LoopFusion/guarded.ll index 8037fce..fb61dde 100644 --- a/llvm/test/Transforms/LoopFusion/guarded.ll +++ b/llvm/test/Transforms/LoopFusion/guarded.ll @@ -360,3 +360,33 @@ for.end: %j.lcssa = phi i64 [ 0, %for.second.guard ], [ %j.02, %for.second.exit ] ret i64 %j.lcssa } + +define void @pr59024() { +; CHECK-LABEL: @pr59024( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 false, label [[FOR_2_PREHEADER:%.*]], label [[FOR_1_PREHEADER:%.*]] +; CHECK: for.1.preheader: +; CHECK-NEXT: br label [[FOR_1:%.*]] +; CHECK: for.1: +; CHECK-NEXT: br i1 true, label [[FOR_2_PREHEADER_LOOPEXIT:%.*]], label [[FOR_1]] +; CHECK: for.2.preheader.loopexit: +; CHECK-NEXT: br label [[FOR_2_PREHEADER]] +; CHECK: for.2.preheader: +; CHECK-NEXT: br label [[FOR_2:%.*]] +; CHECK: for.2: +; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[FOR_2]] +; CHECK: exit: +; CHECK-NEXT: ret void +; +entry: + br i1 false, label %for.2, label %for.1 + +for.1: ; preds = %for.body6, %entry + br i1 true, label %for.2, label %for.1 + +for.2: ; preds = %for.cond13, %for.body6, %entry + br i1 true, label %exit, label %for.2 + +exit: ; preds = %for.cond13 + ret void +} -- 2.7.4