[PATCH] D60284: [JumpThreading] [PR40992] Fix miscompile when folding a successor of an indirectbr
Brian Rzycki via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 4 13:53:29 PDT 2019
brzycki created this revision.
brzycki added reviewers: sebpop, craig.topper, hfinkel.
Herald added subscribers: jfb, hiraditya.
Herald added a project: LLVM.
The `continue` statement in `JumpThreadingPass::ProcessThreadableEdges()` correctly identifies the case when a predecessor is an `indirectbr` or `callbr` and must not be threaded. Unfortunately the bookkeeping for the remaining edges was incorrect and there are cases where a conditional branch in `BB` may be incorrectly folded based on the flawed analysis above. This patch correctly prevents folding in these cases while not fully pessimizing other threading opportunities to the same `BB`.
Thanks to Matthias Liedtke for creating a simplified test-case and concrete failure example.
See PR40992 <https://bugs.llvm.org/show_bug.cgi?id=40992> for debug analysis.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D60284
Files:
llvm/lib/Transforms/Scalar/JumpThreading.cpp
llvm/test/Transforms/JumpThreading/pr40992-indirectbr-folding.ll
Index: llvm/test/Transforms/JumpThreading/pr40992-indirectbr-folding.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/JumpThreading/pr40992-indirectbr-folding.ll
@@ -0,0 +1,42 @@
+; RUN: opt -S < %s -jump-threading | FileCheck %s
+
+; PR40992: Do not incorrectly fold %bb5 into an unconditional br to %bb7.
+; Also verify we correctly thread %bb1 -> %bb7 when %c is false.
+
+define i32 @jtbr(i1 %v1, i1 %v2, i1 %v3) {
+; CHECK: bb0:
+bb0:
+ br label %bb1
+
+; CHECK: bb1:
+bb1:
+ %c = and i1 %v1, %v2
+ br i1 %c, label %bb2, label %bb5
+
+; CHECK: bb2:
+; CHECK: select
+; CHECK-NEXT: indirectbr i8* %ba, [label %bb3, label %bb5]
+bb2:
+ %ba = select i1 %v3, i8* blockaddress(@jtbr, %bb3), i8* blockaddress(@jtbr, %bb4)
+ indirectbr i8* %ba, [label %bb3, label %bb4]
+
+; CHECK: bb3:
+bb3:
+ br label %bb1
+
+; CHECK-NOT: bb4:
+bb4:
+ br label %bb5
+
+; CHECK: bb5:
+bb5:
+ br i1 %c, label %bb6, label %bb7
+
+; CHECK: bb6:
+bb6:
+ ret i32 0
+
+; CHECK: bb7:
+bb7:
+ ret i32 1
+}
Index: llvm/lib/Transforms/Scalar/JumpThreading.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1643,15 +1643,15 @@
OnlyVal = MultipleVal;
}
- // We know where this predecessor is going.
- ++PredWithKnownDest;
-
// If the predecessor ends with an indirect goto, we can't change its
// destination. Same for CallBr.
if (isa<IndirectBrInst>(Pred->getTerminator()) ||
isa<CallBrInst>(Pred->getTerminator()))
continue;
+ // We know where this predecessor is going.
+ ++PredWithKnownDest;
+
PredToDestList.push_back(std::make_pair(Pred, DestBB));
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D60284.193773.patch
Type: text/x-patch
Size: 1802 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190404/27b52139/attachment.bin>
More information about the llvm-commits
mailing list