blob: bb6f32468039ae16dfcb502b002a310f9e0b910b [file] [log] [blame]
commit 1da9834557cd4302a5183b8228ce063e69f82602
Author: Roman Lebedev <lebedev.ri@gmail.com>
Date: Mon Jul 27 15:07:51 2020 +0300
[JumpThreading] ProcessBranchOnXOR(): bailout if any pred ends in indirect branch (PR46857)
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
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 9d0500419a7..2f379b7f616 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -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
index 00000000000..3de7d626513
--- /dev/null
+++ b/llvm/test/Transforms/JumpThreading/pr46857-callbr.ll
@@ -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
+}