Skip to content

Commit 75881db

Browse files
authored
[JumpThreading] Don't phi translate past loop phi (#70664)
When evaluating comparisons in predecessors, phi operands are translated into the predecessor. If the translation is across a backedge, this means that the two operands of the icmp will be from two different loop iterations, resulting in incorrect simplification. Fix this by not performing the phi translation for phis in loop headers. Note: This is not a complete fix. If the jump-threading-across-loop-headers option is enabled, the LoopHeaders variable does not get populated. Additional changes will be needed to fix that case. Related to #70651.
1 parent 33b8586 commit 75881db

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

llvm/lib/Transforms/Scalar/JumpThreading.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,10 @@ bool JumpThreadingPass::computeValueKnownInPredecessorsImpl(
761761
PHINode *PN = dyn_cast<PHINode>(CmpLHS);
762762
if (!PN)
763763
PN = dyn_cast<PHINode>(CmpRHS);
764-
if (PN && PN->getParent() == BB) {
764+
// Do not perform phi translation across a loop header phi, because this
765+
// may result in comparison of values from two different loop iterations.
766+
// FIXME: This check is broken if LoopHeaders is not populated.
767+
if (PN && PN->getParent() == BB && !LoopHeaders.contains(BB)) {
765768
const DataLayout &DL = PN->getModule()->getDataLayout();
766769
// We can do this simplification if any comparisons fold to true or false.
767770
// See if any do.

llvm/test/Transforms/JumpThreading/pr70651.ll

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
22
; RUN: opt -S -passes=jump-threading < %s | FileCheck %s
3+
; RUN: opt -S -passes=jump-threading -jump-threading-across-loop-headers < %s | FileCheck %s --check-prefix=THREAD-LOOP
34

4-
; FIXME: This is a miscompile.
5+
; FIXME: This is a miscompile if -jump-threading-across-loop-headers is enabled.
56
define i64 @test(i64 %v) {
67
; CHECK-LABEL: define i64 @test(
78
; CHECK-SAME: i64 [[V:%.*]]) {
@@ -12,10 +13,24 @@ define i64 @test(i64 %v) {
1213
; CHECK-NEXT: [[SUM:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[SUM_NEXT:%.*]], [[FOR_BODY]] ]
1314
; CHECK-NEXT: [[SUM_NEXT]] = add i64 [[SUM]], [[V]]
1415
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i64 [[SUM_NEXT]], [[SUM]]
15-
; CHECK-NEXT: br i1 [[V_NONNEG]], label [[FOR_BODY]], label [[EXIT:%.*]]
16+
; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[V_NONNEG]], [[OVERFLOW]]
17+
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[EXIT:%.*]]
1618
; CHECK: exit:
1719
; CHECK-NEXT: ret i64 [[SUM]]
1820
;
21+
; THREAD-LOOP-LABEL: define i64 @test(
22+
; THREAD-LOOP-SAME: i64 [[V:%.*]]) {
23+
; THREAD-LOOP-NEXT: entry:
24+
; THREAD-LOOP-NEXT: [[V_NONNEG:%.*]] = icmp sgt i64 [[V]], -1
25+
; THREAD-LOOP-NEXT: br label [[FOR_BODY:%.*]]
26+
; THREAD-LOOP: for.body:
27+
; THREAD-LOOP-NEXT: [[SUM:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[SUM_NEXT:%.*]], [[FOR_BODY]] ]
28+
; THREAD-LOOP-NEXT: [[SUM_NEXT]] = add i64 [[SUM]], [[V]]
29+
; THREAD-LOOP-NEXT: [[OVERFLOW:%.*]] = icmp ult i64 [[SUM_NEXT]], [[SUM]]
30+
; THREAD-LOOP-NEXT: br i1 [[V_NONNEG]], label [[FOR_BODY]], label [[EXIT:%.*]]
31+
; THREAD-LOOP: exit:
32+
; THREAD-LOOP-NEXT: ret i64 [[SUM]]
33+
;
1934
entry:
2035
%v.nonneg = icmp sgt i64 %v, -1
2136
br label %for.body

0 commit comments

Comments
 (0)