[llvm] 34a5c2b - [BasicBlockUtils] Allow critical edge splitting with callbr terminators

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 8 00:23:15 PDT 2022


Author: Nikita Popov
Date: 2022-07-08T09:20:44+02:00
New Revision: 34a5c2bcf266bb5511791803d66304cc58418bdc

URL: https://github.com/llvm/llvm-project/commit/34a5c2bcf266bb5511791803d66304cc58418bdc
DIFF: https://github.com/llvm/llvm-project/commit/34a5c2bcf266bb5511791803d66304cc58418bdc.diff

LOG: [BasicBlockUtils] Allow critical edge splitting with callbr terminators

After D129205, we support SplitBlockPredecessors() for predecessors
with callbr terminators. This means that it is now also safe to
invoke critical edge splitting for an edge coming from a callbr
terminator. Remove checks in various passes that were protecting
against that.

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

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/GVN.cpp
    llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
    llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
    llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll
    llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll
    llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 913034f0c8305..a5a33d93aea6f 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1494,14 +1494,6 @@ bool GVNPass::PerformLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
         return false;
       }
 
-      // FIXME: Can we support the fallthrough edge?
-      if (isa<CallBrInst>(Pred->getTerminator())) {
-        LLVM_DEBUG(
-            dbgs() << "COULD NOT PRE LOAD BECAUSE OF CALLBR CRITICAL EDGE '"
-                   << Pred->getName() << "': " << *Load << '\n');
-        return false;
-      }
-
       if (LoadBB->isEHPad()) {
         LLVM_DEBUG(
             dbgs() << "COULD NOT PRE LOAD BECAUSE OF AN EH PAD CRITICAL EDGE '"
@@ -2875,11 +2867,6 @@ bool GVNPass::performScalarPRE(Instruction *CurInst) {
     if (isa<IndirectBrInst>(PREPred->getTerminator()))
       return false;
 
-    // Don't do PRE across callbr.
-    // FIXME: Can we do this across the fallthrough edge?
-    if (isa<CallBrInst>(PREPred->getTerminator()))
-      return false;
-
     // We can't do PRE safely on a critical edge, so instead we schedule
     // the edge to be split and perform the PRE the next time we iterate
     // on the function.

diff  --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
index 56bb405339fe6..079b2fc973b96 100644
--- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -769,8 +769,7 @@ llvm::SplitAllCriticalEdges(Function &F,
   unsigned NumBroken = 0;
   for (BasicBlock &BB : F) {
     Instruction *TI = BB.getTerminator();
-    if (TI->getNumSuccessors() > 1 && !isa<IndirectBrInst>(TI) &&
-        !isa<CallBrInst>(TI))
+    if (TI->getNumSuccessors() > 1 && !isa<IndirectBrInst>(TI))
       for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
         if (SplitCriticalEdge(TI, i, Options))
           ++NumBroken;

diff  --git a/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp b/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
index 0b36e8708a034..9c595401ce294 100644
--- a/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
+++ b/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
@@ -129,8 +129,7 @@ llvm::SplitKnownCriticalEdge(Instruction *TI, unsigned SuccNum,
   SmallVector<BasicBlock *, 4> LoopPreds;
   // Check if extra modifications will be required to preserve loop-simplify
   // form after splitting. If it would require splitting blocks with IndirectBr
-  // or CallBr terminators, bail out if preserving loop-simplify form is
-  // requested.
+  // terminators, bail out if preserving loop-simplify form is requested.
   if (LI) {
     if (Loop *TIL = LI->getLoopFor(TIBB)) {
 
@@ -156,10 +155,7 @@ llvm::SplitKnownCriticalEdge(Instruction *TI, unsigned SuccNum,
       // Loop-simplify form can be preserved, if we can split all in-loop
       // predecessors.
       if (any_of(LoopPreds, [](BasicBlock *Pred) {
-            const Instruction *T = Pred->getTerminator();
-            if (const auto *CBR = dyn_cast<CallBrInst>(T))
-              return CBR->getDefaultDest() != Pred;
-            return isa<IndirectBrInst>(T);
+            return isa<IndirectBrInst>(Pred->getTerminator());
           })) {
         if (Options.PreserveLoopSimplify)
           return nullptr;

diff  --git a/llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll b/llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll
index 377521d08a853..87fb7fdfd116b 100644
--- a/llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll
+++ b/llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll
@@ -9,19 +9,22 @@
 define void @widget(%struct.pluto** %tmp1) {
 ; CHECK-LABEL: @widget(
 ; CHECK-NEXT:  bb:
-; CHECK-NEXT:    callbr void asm sideeffect "", "i,i"(i8* blockaddress(@widget, [[BB5:%.*]]), i8* blockaddress(@widget, [[BB8:%.*]]))
-; CHECK-NEXT:    to label [[BB4:%.*]] [label [[BB5]], label %bb8]
+; CHECK-NEXT:    callbr void asm sideeffect "", "i,i"(i8* blockaddress(@widget, [[BB5:%.*]]), i8* blockaddress(@widget, [[BB_BB8_CRIT_EDGE:%.*]]))
+; CHECK-NEXT:    to label [[BB4:%.*]] [label [[BB5]], label %bb.bb8_crit_edge]
+; CHECK:       bb.bb8_crit_edge:
+; CHECK-NEXT:    [[TMP10_PRE:%.*]] = load %struct.pluto*, %struct.pluto** [[TMP1:%.*]], align 8
+; CHECK-NEXT:    br label [[BB8:%.*]]
 ; CHECK:       bb4:
 ; CHECK-NEXT:    br label [[BB5]]
 ; CHECK:       bb5:
-; CHECK-NEXT:    [[TMP6:%.*]] = load %struct.pluto*, %struct.pluto** [[TMP1:%.*]]
+; CHECK-NEXT:    [[TMP6:%.*]] = load %struct.pluto*, %struct.pluto** [[TMP1]], align 8
 ; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds [[STRUCT_PLUTO:%.*]], %struct.pluto* [[TMP6]], i64 0, i32 1
 ; CHECK-NEXT:    br label [[BB8]]
 ; CHECK:       bb8:
-; CHECK-NEXT:    [[TMP9:%.*]] = phi i8* [ [[TMP7]], [[BB5]] ], [ null, [[BB:%.*]] ]
-; CHECK-NEXT:    [[TMP10:%.*]] = load %struct.pluto*, %struct.pluto** [[TMP1]]
+; CHECK-NEXT:    [[TMP10:%.*]] = phi %struct.pluto* [ [[TMP6]], [[BB5]] ], [ [[TMP10_PRE]], [[BB_BB8_CRIT_EDGE]] ]
+; CHECK-NEXT:    [[TMP9:%.*]] = phi i8* [ [[TMP7]], [[BB5]] ], [ null, [[BB_BB8_CRIT_EDGE]] ]
 ; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_PLUTO]], %struct.pluto* [[TMP10]], i64 0, i32 0
-; CHECK-NEXT:    [[TMP12:%.*]] = load i8, i8* [[TMP11]]
+; CHECK-NEXT:    [[TMP12:%.*]] = load i8, i8* [[TMP11]], align 1
 ; CHECK-NEXT:    tail call void @spam(i8* [[TMP9]], i8 [[TMP12]])
 ; CHECK-NEXT:    ret void
 ;

diff  --git a/llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll b/llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll
index 9fc37140d2f7c..414614b370903 100644
--- a/llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll
+++ b/llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll
@@ -8,8 +8,11 @@ define void @wombat(i64 %arg, i64* %arg1, i64 %arg2, i32* %arg3) {
 ; CHECK-LABEL: @wombat(
 ; CHECK-NEXT:  bb:
 ; CHECK-NEXT:    [[TMP5:%.*]] = or i64 [[ARG2:%.*]], [[ARG:%.*]]
-; CHECK-NEXT:    callbr void asm sideeffect "", "i,i"(i8* blockaddress(@wombat, [[BB7:%.*]]), i8* blockaddress(@wombat, [[BB9:%.*]]))
-; CHECK-NEXT:    to label [[BB6:%.*]] [label [[BB7]], label %bb9]
+; CHECK-NEXT:    callbr void asm sideeffect "", "i,i"(i8* blockaddress(@wombat, [[BB7:%.*]]), i8* blockaddress(@wombat, [[BB_BB9_CRIT_EDGE:%.*]]))
+; CHECK-NEXT:    to label [[BB6:%.*]] [label [[BB7]], label %bb.bb9_crit_edge]
+; CHECK:       bb.bb9_crit_edge:
+; CHECK-NEXT:    [[DOTPRE:%.*]] = trunc i64 [[TMP5]] to i32
+; CHECK-NEXT:    br label [[BB9:%.*]]
 ; CHECK:       bb6:
 ; CHECK-NEXT:    br label [[BB7]]
 ; CHECK:       bb7:
@@ -17,14 +20,14 @@ define void @wombat(i64 %arg, i64* %arg1, i64 %arg2, i32* %arg3) {
 ; CHECK-NEXT:    tail call void @barney(i32 [[TMP8]])
 ; CHECK-NEXT:    br label [[BB9]]
 ; CHECK:       bb9:
-; CHECK-NEXT:    [[TMP10:%.*]] = trunc i64 [[TMP5]] to i32
-; CHECK-NEXT:    store i32 [[TMP10]], i32* [[ARG3:%.*]]
+; CHECK-NEXT:    [[TMP10_PRE_PHI:%.*]] = phi i32 [ [[DOTPRE]], [[BB_BB9_CRIT_EDGE]] ], [ [[TMP8]], [[BB7]] ]
+; CHECK-NEXT:    store i32 [[TMP10_PRE_PHI]], i32* [[ARG3:%.*]], align 4
 ; CHECK-NEXT:    ret void
 ;
 bb:
   %tmp5 = or i64 %arg2, %arg
   callbr void asm sideeffect "", "i,i"(i8* blockaddress(@wombat, %bb7), i8* blockaddress(@wombat, %bb9))
-          to label %bb6 [label %bb7, label %bb9]
+  to label %bb6 [label %bb7, label %bb9]
 
 bb6:                                              ; preds = %bb
   br label %bb7

diff  --git a/llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting.ll b/llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting.ll
index f2989673de5f2..18b4564cc5390 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/callbr-critical-edge-splitting.ll
@@ -9,8 +9,8 @@ define dso_local i32 @test1() local_unnamed_addr {
 ; LEGACYPM-NEXT:  entry:
 ; LEGACYPM-NEXT:    br label [[FOR_COND:%.*]]
 ; LEGACYPM:       for.cond:
-; LEGACYPM-NEXT:    callbr void asm sideeffect "", "i,i,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@test1, [[COND_TRUE_I:%.*]]), i8* blockaddress(@test1, [[FOR_END:%.*]]))
-; LEGACYPM-NEXT:    to label [[ASM_FALLTHROUGH_I_I:%.*]] [label [[COND_TRUE_I]], label %for.end]
+; LEGACYPM-NEXT:    callbr void asm sideeffect "", "i,i,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@test1, [[COND_TRUE_I:%.*]]), i8* blockaddress(@test1, [[FOR_ENDSPLIT:%.*]]))
+; LEGACYPM-NEXT:    to label [[ASM_FALLTHROUGH_I_I:%.*]] [label [[COND_TRUE_I]], label %for.endsplit]
 ; LEGACYPM:       asm.fallthrough.i.i:
 ; LEGACYPM-NEXT:    unreachable
 ; LEGACYPM:       cond.true.i:
@@ -20,11 +20,15 @@ define dso_local i32 @test1() local_unnamed_addr {
 ; LEGACYPM-NEXT:    [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], 1
 ; LEGACYPM-NEXT:    br i1 true, label [[DO_BODY_I_I_RDRAND_INT_EXIT_I_CRIT_EDGE:%.*]], label [[DO_BODY_I_I_DO_BODY_I_I_CRIT_EDGE]]
 ; LEGACYPM:       do.body.i.i.rdrand_int.exit.i_crit_edge:
-; LEGACYPM-NEXT:    br i1 true, label [[FOR_END]], label [[FOR_INC:%.*]]
+; LEGACYPM-NEXT:    br i1 true, label [[DO_BODY_I_I_RDRAND_INT_EXIT_I_CRIT_EDGE_FOR_END_CRIT_EDGE:%.*]], label [[FOR_INC:%.*]]
+; LEGACYPM:       do.body.i.i.rdrand_int.exit.i_crit_edge.for.end_crit_edge:
+; LEGACYPM-NEXT:    br label [[FOR_END:%.*]]
 ; LEGACYPM:       for.inc:
 ; LEGACYPM-NEXT:    br label [[FOR_COND]]
+; LEGACYPM:       for.endsplit:
+; LEGACYPM-NEXT:    br label [[FOR_END]]
 ; LEGACYPM:       for.end:
-; LEGACYPM-NEXT:    [[PGOCOUNT_PROMOTED24:%.*]] = phi i64 [ undef, [[FOR_COND]] ], [ [[LSR_IV_NEXT]], [[DO_BODY_I_I_RDRAND_INT_EXIT_I_CRIT_EDGE]] ]
+; LEGACYPM-NEXT:    [[PGOCOUNT_PROMOTED24:%.*]] = phi i64 [ [[LSR_IV_NEXT]], [[DO_BODY_I_I_RDRAND_INT_EXIT_I_CRIT_EDGE_FOR_END_CRIT_EDGE]] ], [ undef, [[FOR_ENDSPLIT]] ]
 ; LEGACYPM-NEXT:    ret i32 undef
 ;
 ; NEWPM-LABEL: @test1(


        


More information about the llvm-commits mailing list