[llvm] 11079e8 - [IR] Don't treat callbr as indirect terminator

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 18 00:32:17 PDT 2022


Author: Nikita Popov
Date: 2022-07-18T09:32:08+02:00
New Revision: 11079e8820ab58417365c226d39f2615b0bef685

URL: https://github.com/llvm/llvm-project/commit/11079e8820ab58417365c226d39f2615b0bef685
DIFF: https://github.com/llvm/llvm-project/commit/11079e8820ab58417365c226d39f2615b0bef685.diff

LOG: [IR] Don't treat callbr as indirect terminator

Callbr is no longer an indirect terminator in the sense that is
relevant here (that it's successors cannot be updated). The primary
effect of this change is that callbr no longer prevents formation
of loop simplify form.

I decided to drop the isIndirectTerminator() method entirely and
replace it with isa<IndirectBrInst>() checks. I assume this method
was added to abstract over indirectbr and callbr, but it never
really caught on, and there is nothing left to abstract anymore
at this point.

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

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/SparsePropagation.h
    llvm/include/llvm/IR/Instruction.h
    llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
    llvm/lib/Transforms/Utils/LoopSimplify.cpp
    llvm/test/Transforms/LoopDeletion/two-predecessors.ll
    llvm/test/Transforms/LoopRotate/callbr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/SparsePropagation.h b/llvm/include/llvm/Analysis/SparsePropagation.h
index 428238c5fa0bc..d5805a7314757 100644
--- a/llvm/include/llvm/Analysis/SparsePropagation.h
+++ b/llvm/include/llvm/Analysis/SparsePropagation.h
@@ -331,8 +331,8 @@ void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::getFeasibleSuccessors(
     return;
   }
 
-  if (TI.isExceptionalTerminator() ||
-      TI.isIndirectTerminator()) {
+  if (!isa<SwitchInst>(TI)) {
+    // Unknown termintor, assume all successors are feasible.
     Succs.assign(Succs.size(), true);
     return;
   }

diff  --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index 8d0a8363cdfb4..15b0bdf557fb1 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -172,10 +172,6 @@ class Instruction : public User,
   /// its operands.
   bool isOnlyUserOfAnyOperand();
 
-  bool isIndirectTerminator() const {
-    return isIndirectTerminator(getOpcode());
-  }
-
   static const char* getOpcodeName(unsigned OpCode);
 
   static inline bool isTerminator(unsigned OpCode) {
@@ -242,17 +238,6 @@ class Instruction : public User,
     }
   }
 
-  /// Returns true if the OpCode is a terminator with indirect targets.
-  static inline bool isIndirectTerminator(unsigned OpCode) {
-    switch (OpCode) {
-    case Instruction::IndirectBr:
-    case Instruction::CallBr:
-      return true;
-    default:
-      return false;
-    }
-  }
-
   //===--------------------------------------------------------------------===//
   // Metadata manipulation.
   //===--------------------------------------------------------------------===//

diff  --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
index 0f33559c7e70d..597c88ad13df1 100644
--- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
@@ -622,7 +622,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
         // We only need to split loop exit edges.
         Loop *PredLoop = LI->getLoopFor(ExitPred);
         if (!PredLoop || PredLoop->contains(Exit) ||
-            ExitPred->getTerminator()->isIndirectTerminator())
+            isa<IndirectBrInst>(ExitPred->getTerminator()))
           continue;
         SplitLatchEdge |= L->getLoopLatch() == ExitPred;
         BasicBlock *ExitSplit = SplitCriticalEdge(

diff  --git a/llvm/lib/Transforms/Utils/LoopSimplify.cpp b/llvm/lib/Transforms/Utils/LoopSimplify.cpp
index 55d5c733733b9..2ff8a3f7b2286 100644
--- a/llvm/lib/Transforms/Utils/LoopSimplify.cpp
+++ b/llvm/lib/Transforms/Utils/LoopSimplify.cpp
@@ -127,7 +127,7 @@ BasicBlock *llvm::InsertPreheaderForLoop(Loop *L, DominatorTree *DT,
       // If the loop is branched to from an indirect terminator, we won't
       // be able to fully transform the loop, because it prohibits
       // edge splitting.
-      if (P->getTerminator()->isIndirectTerminator())
+      if (isa<IndirectBrInst>(P->getTerminator()))
         return nullptr;
 
       // Keep track of it.
@@ -256,7 +256,7 @@ static Loop *separateNestedLoop(Loop *L, BasicBlock *Preheader,
     if (PN->getIncomingValue(i) != PN ||
         !L->contains(PN->getIncomingBlock(i))) {
       // We can't split indirect control flow edges.
-      if (PN->getIncomingBlock(i)->getTerminator()->isIndirectTerminator())
+      if (isa<IndirectBrInst>(PN->getIncomingBlock(i)->getTerminator()))
         return nullptr;
       OuterLoopPreds.push_back(PN->getIncomingBlock(i));
     }
@@ -375,7 +375,7 @@ static BasicBlock *insertUniqueBackedgeBlock(Loop *L, BasicBlock *Preheader,
   std::vector<BasicBlock*> BackedgeBlocks;
   for (BasicBlock *P : predecessors(Header)) {
     // Indirect edges cannot be split, so we must fail if we find one.
-    if (P->getTerminator()->isIndirectTerminator())
+    if (isa<IndirectBrInst>(P->getTerminator()))
       return nullptr;
 
     if (P != Preheader) BackedgeBlocks.push_back(P);

diff  --git a/llvm/test/Transforms/LoopDeletion/two-predecessors.ll b/llvm/test/Transforms/LoopDeletion/two-predecessors.ll
index b6476b3532cbb..5aed27334144b 100644
--- a/llvm/test/Transforms/LoopDeletion/two-predecessors.ll
+++ b/llvm/test/Transforms/LoopDeletion/two-predecessors.ll
@@ -8,11 +8,13 @@ define dso_local i32 @hoge() local_unnamed_addr #0 {
 ; CHECK-LABEL: @hoge(
 ; CHECK-NEXT:  bb:
 ; CHECK-NEXT:    callbr void asm sideeffect "", "!i"()
-; CHECK-NEXT:    to label [[BB1:%.*]] [label %bb2]
+; CHECK-NEXT:    to label [[BB1:%.*]] [label %bb2.preheader]
 ; CHECK:       bb1:
+; CHECK-NEXT:    br label [[BB2_PREHEADER:%.*]]
+; CHECK:       bb2.preheader:
 ; CHECK-NEXT:    br label [[BB2:%.*]]
 ; CHECK:       bb2:
-; CHECK-NEXT:    [[TMP:%.*]] = phi i32 [ undef, [[BB1]] ], [ [[TMP3:%.*]], [[BB2]] ], [ undef, [[BB:%.*]] ]
+; CHECK-NEXT:    [[TMP:%.*]] = phi i32 [ [[TMP3:%.*]], [[BB2]] ], [ undef, [[BB2_PREHEADER]] ]
 ; CHECK-NEXT:    [[TMP3]] = tail call i32 bitcast (i32 (...)* @widget to i32 (i32)*)(i32 [[TMP]])
 ; CHECK-NEXT:    br label [[BB2]]
 ;

diff  --git a/llvm/test/Transforms/LoopRotate/callbr.ll b/llvm/test/Transforms/LoopRotate/callbr.ll
index c24a9105b6859..da5f7876fac8f 100644
--- a/llvm/test/Transforms/LoopRotate/callbr.ll
+++ b/llvm/test/Transforms/LoopRotate/callbr.ll
@@ -13,10 +13,11 @@ define i32 @o() #0 {
 ; CHECK-NEXT:    [[TMP2:%.*]] = load i8*, i8** bitcast (i64* @d to i8**), align 8
 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* @f, align 4
 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
-; CHECK-NEXT:    br i1 [[TMP4]], label [[TMP17:%.*]], label [[DOTLR_PH2:%.*]]
-; CHECK:       .lr.ph2:
+; CHECK-NEXT:    br i1 [[TMP4]], label [[TMP17:%.*]], label [[DOTLR_PH4:%.*]]
+; CHECK:       .lr.ph4:
 ; CHECK-NEXT:    br label [[TMP5:%.*]]
-; CHECK:         [[TMP6:%.*]] = phi i32 [ [[TMP3]], [[DOTLR_PH2]] ], [ [[TMP15:%.*]], [[M_EXIT:%.*]] ]
+; CHECK:       5:
+; CHECK-NEXT:    [[TMP6:%.*]] = phi i32 [ [[TMP3]], [[DOTLR_PH4]] ], [ [[TMP15:%.*]], [[M_EXIT:%.*]] ]
 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp ult i32 [[TMP6]], 4
 ; CHECK-NEXT:    [[TMP8:%.*]] = zext i1 [[TMP7]] to i32
 ; CHECK-NEXT:    store i32 [[TMP8]], i32* @g, align 4
@@ -30,26 +31,31 @@ define i32 @o() #0 {
 ; CHECK-NEXT:    br i1 [[TMP12]], label [[M_EXIT]], label [[DOTLR_PH:%.*]]
 ; CHECK:       .lr.ph:
 ; CHECK-NEXT:    br label [[TMP13:%.*]]
-; CHECK:         [[DOT11:%.*]] = phi i32 [ undef, [[DOTLR_PH]] ], [ [[TMP14:%.*]], [[J_EXIT_I:%.*]] ]
-; CHECK-NEXT:    callbr void asm sideeffect "", "!i,~{dirflag},~{fpsr},~{flags}"() #1
-; CHECK-NEXT:    to label [[J_EXIT_I]] [label %m.exit]
+; CHECK:       13:
+; CHECK-NEXT:    [[DOT11:%.*]] = phi i32 [ undef, [[DOTLR_PH]] ], [ [[TMP14:%.*]], [[J_EXIT_I:%.*]] ]
+; CHECK-NEXT:    callbr void asm sideeffect "", "!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1:[0-9]+]]
+; CHECK-NEXT:    to label [[J_EXIT_I]] [label %.m.exit_crit_edge]
 ; CHECK:       j.exit.i:
-; CHECK-NEXT:    [[TMP14]] = tail call i32 asm "", "={ax},~{dirflag},~{fpsr},~{flags}"() #2
-; CHECK-NEXT:    br i1 [[TMP12]], label [[DOTM_EXIT_CRIT_EDGE:%.*]], label [[TMP13]]
+; CHECK-NEXT:    [[TMP14]] = tail call i32 asm "", "={ax},~{dirflag},~{fpsr},~{flags}"() #[[ATTR2:[0-9]+]]
+; CHECK-NEXT:    br i1 [[TMP12]], label [[DOTM_EXIT_CRIT_EDGE2:%.*]], label [[TMP13]]
 ; CHECK:       .m.exit_crit_edge:
-; CHECK-NEXT:    [[SPLIT:%.*]] = phi i32 [ [[TMP14]], [[J_EXIT_I]] ]
+; CHECK-NEXT:    [[SPLIT:%.*]] = phi i32 [ [[DOT11]], [[TMP13]] ]
+; CHECK-NEXT:    br label [[M_EXIT]]
+; CHECK:       .m.exit_crit_edge2:
+; CHECK-NEXT:    [[SPLIT3:%.*]] = phi i32 [ [[TMP14]], [[J_EXIT_I]] ]
 ; CHECK-NEXT:    br label [[M_EXIT]]
 ; CHECK:       m.exit:
-; CHECK-NEXT:    [[DOT1_LCSSA:%.*]] = phi i32 [ [[DOT11]], [[TMP13]] ], [ [[SPLIT]], [[DOTM_EXIT_CRIT_EDGE]] ], [ undef, [[THREAD_PRE_SPLIT]] ]
+; CHECK-NEXT:    [[DOT1_LCSSA:%.*]] = phi i32 [ [[SPLIT]], [[DOTM_EXIT_CRIT_EDGE:%.*]] ], [ [[SPLIT3]], [[DOTM_EXIT_CRIT_EDGE2]] ], [ undef, [[THREAD_PRE_SPLIT]] ]
 ; CHECK-NEXT:    store i32 [[DOT1_LCSSA]], i32* @h, align 4
 ; CHECK-NEXT:    [[TMP15]] = load i32, i32* @f, align 4
 ; CHECK-NEXT:    [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0
-; CHECK-NEXT:    br i1 [[TMP16]], label [[DOT_CRIT_EDGE3:%.*]], label [[TMP5]]
+; CHECK-NEXT:    br i1 [[TMP16]], label [[DOT_CRIT_EDGE5:%.*]], label [[TMP5]]
 ; CHECK:       ._crit_edge:
 ; CHECK-NEXT:    br label [[TMP17]]
-; CHECK:       ._crit_edge3:
+; CHECK:       ._crit_edge5:
 ; CHECK-NEXT:    br label [[TMP17]]
-; CHECK:         ret i32 undef
+; CHECK:       17:
+; CHECK-NEXT:    ret i32 undef
 ;
   %1 = alloca [1 x i32], align 4
   %2 = load i8*, i8** bitcast (i64* @d to i8**), align 8


        


More information about the llvm-commits mailing list