[llvm] r367154 - [JumpThreading] Stop searching predecessor when the current bb is in a

Wei Mi via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 26 13:59:22 PDT 2019


Author: wmi
Date: Fri Jul 26 13:59:22 2019
New Revision: 367154

URL: http://llvm.org/viewvc/llvm-project?rev=367154&view=rev
Log:
[JumpThreading] Stop searching predecessor when the current bb is in a
unreachable loop.

updatePredecessorProfileMetadata in jumpthreading tries to find the
first dominating predecessor block for a PHI value by searching upwards
the predecessor block chain.

But jumpthreading may see some temporary IR state which contains
unreachable bb not being cleaned up. If an unreachable loop happens to
be on the predecessor block chain, keeping chasing the predecessor
block will run into an infinite loop.

The patch fixes it.

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


Added:
    llvm/trunk/test/Transforms/JumpThreading/unreachable-loops.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=367154&r1=367153&r2=367154&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Fri Jul 26 13:59:22 2019
@@ -224,13 +224,21 @@ static void updatePredecessorProfileMeta
          BasicBlock *PhiBB) -> std::pair<BasicBlock *, BasicBlock *> {
     auto *PredBB = IncomingBB;
     auto *SuccBB = PhiBB;
+    SmallPtrSet<BasicBlock *, 16> Visited;
     while (true) {
       BranchInst *PredBr = dyn_cast<BranchInst>(PredBB->getTerminator());
       if (PredBr && PredBr->isConditional())
         return {PredBB, SuccBB};
+      Visited.insert(PredBB);
       auto *SinglePredBB = PredBB->getSinglePredecessor();
       if (!SinglePredBB)
         return {nullptr, nullptr};
+
+      // Stop searching when SinglePredBB has been visited. It means we see
+      // an unreachable loop.
+      if (Visited.count(SinglePredBB))
+        return {nullptr, nullptr};
+
       SuccBB = PredBB;
       PredBB = SinglePredBB;
     }
@@ -253,7 +261,9 @@ static void updatePredecessorProfileMeta
       return;
 
     BasicBlock *PredBB = PredOutEdge.first;
-    BranchInst *PredBr = cast<BranchInst>(PredBB->getTerminator());
+    BranchInst *PredBr = dyn_cast<BranchInst>(PredBB->getTerminator());
+    if (!PredBr)
+      return;
 
     uint64_t PredTrueWeight, PredFalseWeight;
     // FIXME: We currently only set the profile data when it is missing.

Added: llvm/trunk/test/Transforms/JumpThreading/unreachable-loops.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/unreachable-loops.ll?rev=367154&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/JumpThreading/unreachable-loops.ll (added)
+++ llvm/trunk/test/Transforms/JumpThreading/unreachable-loops.ll Fri Jul 26 13:59:22 2019
@@ -0,0 +1,63 @@
+; RUN: opt -jump-threading -S < %s | FileCheck %s
+; RUN: opt -passes=jump-threading -S < %s | FileCheck %s
+; Check the unreachable loop won't cause infinite loop
+; in jump-threading when it tries to update the predecessors'
+; profile metadata from a phi node.
+
+define void @unreachable_single_bb_loop() {
+; CHECK-LABEL: @unreachable_single_bb_loop()
+bb:
+  %tmp = call i32 @a()
+  %tmp1 = icmp eq i32 %tmp, 1
+  br i1 %tmp1, label %bb5, label %bb8
+
+; unreachable single bb loop.
+bb2:                                              ; preds = %bb2
+  %tmp4 = icmp ne i32 %tmp, 1
+  switch i1 %tmp4, label %bb2 [
+    i1 0, label %bb5
+    i1 1, label %bb8
+  ]
+
+bb5:                                              ; preds = %bb2, %bb
+  %tmp6 = phi i1 [ %tmp1, %bb ], [ false, %bb2 ]
+  br i1 %tmp6, label %bb8, label %bb7, !prof !0
+
+bb7:                                              ; preds = %bb5
+  br label %bb8
+
+bb8:                                              ; preds = %bb8, %bb7, %bb5, %bb2
+  ret void
+}
+
+define void @unreachable_multi_bbs_loop() {
+; CHECK-LABEL: @unreachable_multi_bbs_loop()
+bb:
+  %tmp = call i32 @a()
+  %tmp1 = icmp eq i32 %tmp, 1
+  br i1 %tmp1, label %bb5, label %bb8
+
+; unreachable two bbs loop.
+bb3:                                              ; preds = %bb2
+  br label %bb2
+
+bb2:                                              ; preds = %bb3
+  %tmp4 = icmp ne i32 %tmp, 1
+  switch i1 %tmp4, label %bb3 [
+    i1 0, label %bb5
+    i1 1, label %bb8
+  ]
+
+bb5:                                              ; preds = %bb2, %bb
+  %tmp6 = phi i1 [ %tmp1, %bb ], [ false, %bb2 ]
+  br i1 %tmp6, label %bb8, label %bb7, !prof !0
+
+bb7:                                              ; preds = %bb5
+  br label %bb8
+
+bb8:                                              ; preds = %bb8, %bb7, %bb5, %bb2
+  ret void
+}
+declare i32 @a()
+
+!0 = !{!"branch_weights", i32 2146410443, i32 1073205}




More information about the llvm-commits mailing list