[JumpThreading] ProcessBranchOnXOR(): bailout if any pred ends in indirect branch...
authorRoman Lebedev <lebedev.ri@gmail.com>
Mon, 27 Jul 2020 12:07:51 +0000 (15:07 +0300)
committerRoman Lebedev <lebedev.ri@gmail.com>
Mon, 27 Jul 2020 12:39:03 +0000 (15:39 +0300)
SplitBlockPredecessors() can not split blocks that have such terminators,
and in two other places we already ensure that we don't end up calling
SplitBlockPredecessors() on such blocks. Do so in one more place.

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

llvm/lib/Transforms/Scalar/JumpThreading.cpp
llvm/test/Transforms/JumpThreading/pr46857-callbr.ll [new file with mode: 0644]

index 9d05004..2f379b7 100644 (file)
@@ -1859,6 +1859,14 @@ bool JumpThreadingPass::ProcessBranchOnXOR(BinaryOperator *BO) {
     return true;
   }
 
+  // If any of predecessors end with an indirect goto, we can't change its
+  // destination. Same for CallBr.
+  if (any_of(BlocksToFoldInto, [](BasicBlock *Pred) {
+        return isa<IndirectBrInst>(Pred->getTerminator()) ||
+               isa<CallBrInst>(Pred->getTerminator());
+      }))
+    return false;
+
   // Try to duplicate BB into PredBB.
   return DuplicateCondBranchOnPHIIntoPred(BB, BlocksToFoldInto);
 }
diff --git a/llvm/test/Transforms/JumpThreading/pr46857-callbr.ll b/llvm/test/Transforms/JumpThreading/pr46857-callbr.ll
new file mode 100644 (file)
index 0000000..3de7d62
--- /dev/null
@@ -0,0 +1,52 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -jump-threading -S | FileCheck %s
+
+; CHECK-ALL-LABEL: @func(
+
+define i1 @func(i1 %arg, i32 %arg1, i1 %arg2) {
+; CHECK-LABEL: @func(
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    br i1 [[ARG:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
+; CHECK:       bb3:
+; CHECK-NEXT:    [[I:%.*]] = icmp eq i32 [[ARG1:%.*]], 0
+; CHECK-NEXT:    br label [[BB7:%.*]]
+; CHECK:       bb4:
+; CHECK-NEXT:    callbr void asm sideeffect "", "X"(i8* blockaddress(@func, [[BB7]]))
+; CHECK-NEXT:    to label [[BB5:%.*]] [label %bb7]
+; CHECK:       bb5:
+; CHECK-NEXT:    br label [[BB7]]
+; CHECK:       bb7:
+; CHECK-NEXT:    [[I8:%.*]] = phi i1 [ [[I]], [[BB3]] ], [ [[ARG2:%.*]], [[BB5]] ], [ [[ARG2]], [[BB4]] ]
+; CHECK-NEXT:    [[I9:%.*]] = xor i1 [[I8]], [[ARG]]
+; CHECK-NEXT:    br i1 [[I9]], label [[BB11:%.*]], label [[BB11]]
+; CHECK:       bb11:
+; CHECK-NEXT:    ret i1 [[I9]]
+;
+bb:
+  br i1 %arg, label %bb3, label %bb4
+
+bb3:
+  %i = icmp eq i32 %arg1, 0
+  br label %bb7
+
+bb4:
+  callbr void asm sideeffect "", "X"(i8* blockaddress(@func, %bb6))
+  to label %bb5 [label %bb6]
+
+bb5:
+  br label %bb6
+
+bb6:
+  br label %bb7
+
+bb7:
+  %i8 = phi i1 [ %i, %bb3 ], [ %arg2, %bb6 ]
+  %i9 = xor i1 %i8, %arg
+  br i1 %i9, label %bb11, label %bb10
+
+bb10:
+  br label %bb11
+
+bb11:
+  ret i1 %i9
+}