Skip to content

Commit 7eac876

Browse files
d-makogontru
authored andcommitted
[LVI] Disable at-use reasoning across phi nodes (PR60629)
For phi nodes, while we can make use of the edge condition for the incoming value, we shouldn't look past the phi node to look for further conditions, because we might be reasoning about values from two different cycle iterations (which will have the same SSA value). To handle this more specifically we would have to detect cycles, and there doesn't seem to be any motivating case for that at this point.
1 parent b98d959 commit 7eac876

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

llvm/lib/Analysis/LazyValueInfo.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,19 +1673,20 @@ ConstantRange LazyValueInfo::getConstantRangeAtUse(const Use &U,
16731673
// TODO: Use non-local query?
16741674
CondVal =
16751675
getEdgeValueLocal(V, PHI->getIncomingBlock(*CurrU), PHI->getParent());
1676-
} else if (!isSafeToSpeculativelyExecute(CurrI)) {
1677-
// Stop walking if we hit a non-speculatable instruction. Even if the
1678-
// result is only used under a specific condition, executing the
1679-
// instruction itself may cause side effects or UB already.
1680-
break;
16811676
}
16821677
if (CondVal && CondVal->isConstantRange())
16831678
CR = CR.intersectWith(CondVal->getConstantRange());
16841679

16851680
// Only follow one-use chain, to allow direct intersection of conditions.
16861681
// If there are multiple uses, we would have to intersect with the union of
16871682
// all conditions at different uses.
1688-
if (!CurrI->hasOneUse())
1683+
// Stop walking if we hit a non-speculatable instruction. Even if the
1684+
// result is only used under a specific condition, executing the
1685+
// instruction itself may cause side effects or UB already.
1686+
// This also disallows looking through phi nodes: If the phi node is part
1687+
// of a cycle, we might end up reasoning about values from different cycle
1688+
// iterations (PR60629).
1689+
if (!CurrI->hasOneUse() || !isSafeToSpeculativelyExecute(CurrI))
16891690
break;
16901691
CurrU = &*CurrI->use_begin();
16911692
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -passes=correlated-propagation -S %s | FileCheck %s
3+
4+
; Check that shift is not removed by CVP because of incorrect range returned by LVI::getConstantRangeAtUse.
5+
; https://github.com/llvm/llvm-project/issues/60629
6+
7+
define i32 @test(i32 %arg) {
8+
; CHECK-LABEL: @test(
9+
; CHECK-NEXT: entry:
10+
; CHECK-NEXT: br label [[LOOP:%.*]]
11+
; CHECK: loop:
12+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 127, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[DO_SHIFT:%.*]] ]
13+
; CHECK-NEXT: [[SHIFTED_IV:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SHIFT:%.*]], [[DO_SHIFT]] ]
14+
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
15+
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp sgt i32 [[IV]], 127
16+
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[DO_SHIFT]]
17+
; CHECK: do.shift:
18+
; CHECK-NEXT: [[SHIFT]] = ashr i32 [[IV]], [[ARG:%.*]]
19+
; CHECK-NEXT: br label [[LOOP]]
20+
; CHECK: bb1:
21+
; CHECK-NEXT: br label [[EXIT]]
22+
; CHECK: exit:
23+
; CHECK-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[BB1:%.*]] ], [ [[SHIFTED_IV]], [[LOOP]] ]
24+
; CHECK-NEXT: ret i32 [[RETVAL]]
25+
;
26+
entry:
27+
br label %loop
28+
29+
loop: ; preds = %do.shift, %entry
30+
%iv = phi i32 [ 127, %entry ], [ %iv.next, %do.shift ]
31+
%shifted.iv = phi i32 [ 0, %entry ], [ %shift, %do.shift ]
32+
%iv.next = add i32 %iv, 1
33+
%loop_cond = icmp sgt i32 %iv, 127
34+
br i1 %loop_cond, label %exit, label %do.shift
35+
36+
do.shift: ; preds = %loop
37+
%shift = ashr i32 %iv, %arg
38+
br label %loop
39+
40+
bb1: ; No predecessors!
41+
br label %exit
42+
43+
exit: ; preds = %loop, %bb1
44+
%retval = phi i32 [ 0, %bb1 ], [ %shifted.iv, %loop ]
45+
ret i32 %retval
46+
}

0 commit comments

Comments
 (0)