[llvm] 6a82ace - [LoopFusion] Bails out if only the second candidate is guarded (PR48060)

Ta-Wei Tu via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 5 10:09:02 PDT 2021


Author: Ta-Wei Tu
Date: 2021-04-06T01:08:56+08:00
New Revision: 6a82ace5f27fda10963f8b7b12299b61458d4904

URL: https://github.com/llvm/llvm-project/commit/6a82ace5f27fda10963f8b7b12299b61458d4904
DIFF: https://github.com/llvm/llvm-project/commit/6a82ace5f27fda10963f8b7b12299b61458d4904.diff

LOG: [LoopFusion] Bails out if only the second candidate is guarded (PR48060)

If only the second candidate loop is guarded while the first one is not, fusioning
two loops might not be valid but this check is currently missing.

Fixes https://bugs.llvm.org/show_bug.cgi?id=48060

Reviewed By: sidbav

Differential Revision: https://reviews.llvm.org/D99716

Added: 
    llvm/test/Transforms/LoopFusion/pr48060.ll

Modified: 
    llvm/lib/Transforms/Scalar/LoopFuse.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
index b5f8dfa9aafb..63f02d026916 100644
--- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
@@ -99,6 +99,8 @@ STATISTIC(NonEmptyExitBlock, "Candidate has a non-empty exit block with "
 STATISTIC(NonEmptyGuardBlock, "Candidate has a non-empty guard block with "
                               "instructions that cannot be moved");
 STATISTIC(NotRotated, "Candidate is not rotated");
+STATISTIC(OnlySecondCandidateIsGuarded,
+          "The second candidate is guarded while the first one is not");
 
 enum FusionDependenceAnalysisChoice {
   FUSION_DEPENDENCE_ANALYSIS_SCEV,
@@ -891,6 +893,14 @@ struct LoopFuser {
             continue;
           }
 
+          if (!FC0->GuardBranch && FC1->GuardBranch) {
+            LLVM_DEBUG(dbgs() << "The second candidate is guarded while the "
+                                 "first one is not. Not fusing.\n");
+            reportLoopFusion<OptimizationRemarkMissed>(
+                *FC0, *FC1, OnlySecondCandidateIsGuarded);
+            continue;
+          }
+
           // Ensure that FC0 and FC1 have identical guards.
           // If one (or both) are not guarded, this check is not necessary.
           if (FC0->GuardBranch && FC1->GuardBranch &&

diff  --git a/llvm/test/Transforms/LoopFusion/pr48060.ll b/llvm/test/Transforms/LoopFusion/pr48060.ll
new file mode 100644
index 000000000000..15a98a8f71c0
--- /dev/null
+++ b/llvm/test/Transforms/LoopFusion/pr48060.ll
@@ -0,0 +1,69 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -loop-fusion < %s | FileCheck %s
+; RUN: opt -S -loop-fusion -pass-remarks-output=%t < %s
+; RUN: FileCheck --input-file=%t %s --check-prefix REMARKS
+
+define dso_local void @pr48060(i1 %cond) {
+; CHECK-LABEL: @pr48060(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[FOR_1_PH:%.*]]
+; CHECK:       for.1.ph:
+; CHECK-NEXT:    br label [[FOR_1:%.*]]
+; CHECK:       for.1:
+; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[FOR_1_PH]] ], [ [[I_NEXT:%.*]], [[FOR_1]] ]
+; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
+; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i32 [[I_NEXT]], 10
+; CHECK-NEXT:    br i1 [[COND_1]], label [[FOR_1_EXIT:%.*]], label [[FOR_1]]
+; CHECK:       for.1.exit:
+; CHECK-NEXT:    br i1 [[COND:%.*]], label [[END:%.*]], label [[FOR_2_PH:%.*]]
+; CHECK:       for.2.ph:
+; CHECK-NEXT:    br label [[FOR_2:%.*]]
+; CHECK:       for.2:
+; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[FOR_2_PH]] ], [ [[J_NEXT:%.*]], [[FOR_2]] ]
+; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
+; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[J_NEXT]], 10
+; CHECK-NEXT:    br i1 [[COND_2]], label [[FOR_2_EXIT:%.*]], label [[FOR_2]]
+; CHECK:       for.2.exit:
+; CHECK-NEXT:    br label [[END]]
+; CHECK:       end:
+; CHECK-NEXT:    ret void
+;
+
+; REMARKS:      --- !Missed
+; REMARKS-NEXT: Pass:            loop-fusion
+; REMARKS-NEXT: Name:            OnlySecondCandidateIsGuarded
+; REMARKS-NEXT: Function:        pr48060
+; REMARKS-NEXT: Args:
+; REMARKS:        - Cand1:           for.1.ph
+; REMARKS:        - Cand2:           for.2.ph
+; REMARKS:        - String:          The second candidate is guarded while the first one is not
+entry:
+  br label %for.1.ph
+
+for.1.ph:                                         ; preds = %entry
+  br label %for.1
+
+for.1:                                            ; preds = %for.1, %for.1.ph
+  %i = phi i32 [ 0, %for.1.ph ], [ %i.next, %for.1 ]
+  %i.next = add i32 %i, 1
+  %cond.1 = icmp eq i32 %i.next, 10
+  br i1 %cond.1, label %for.1.exit, label %for.1
+
+for.1.exit:                                       ; preds = %for.1
+  br i1 %cond, label %end, label %for.2.ph
+
+for.2.ph:                                         ; preds = %for.1.exit
+  br label %for.2
+
+for.2:                                            ; preds = %for.2, %for.2.ph
+  %j = phi i32 [ 0, %for.2.ph ], [ %j.next, %for.2 ]
+  %j.next = add i32 %j, 1
+  %cond.2 = icmp eq i32 %j.next, 10
+  br i1 %cond.2, label %for.2.exit, label %for.2
+
+for.2.exit:                                       ; preds = %for.2
+  br label %end
+
+end:                                              ; preds = %for.1.exit, %for.2.exit
+  ret void
+}


        


More information about the llvm-commits mailing list