Skip to content

Commit ea45fec

Browse files
authored
[PredicateInfo] Reserve adjacent LN_Last defs for the same phi use (#164577)
This patch fixes a missed optimization issue: predicate infos might be lost in phi-use scenarios. Due to the existence of and-chains, a phi-use might be associated with multiple LN_Last predicate infos. E.g., ```cpp // TWO LN_Last Predicate Info defs: // 1. a >= 1 // 2. a < 2 if ( a < 1 || a >= 2) { a = 1; } // PHI use of `a` use(a) ``` However, previously, `popStackUntilDFSScope` reserved only ONE LN_Last def for a phi use (i.e., reserve only one of `a >= 1` / `a < 2`), although there might be multiple LN_Last defs for the same phi use. This patch reserves the adjacent LN_Last defs if they are designated for the same phi use.
1 parent 0b9ed5d commit ea45fec

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

llvm/lib/Transforms/Utils/PredicateInfo.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,16 @@ bool PredicateInfoBuilder::stackIsInScope(const ValueDFSStack &Stack,
260260
// next to the defs they must go with so that we can know it's time to pop
261261
// the stack when we hit the end of the phi uses for a given def.
262262
const ValueDFS &Top = *Stack.back().V;
263-
if (Top.LocalNum == LN_Last && Top.PInfo) {
264-
if (!VDUse.U)
265-
return false;
263+
assert(Top.PInfo && "RenameStack should only contain predicate infos (defs)");
264+
if (Top.LocalNum == LN_Last) {
265+
if (!VDUse.U) {
266+
assert(VDUse.PInfo && "A non-use VDUse should have a predicate info");
267+
// We should reserve adjacent LN_Last defs for the same phi use.
268+
return VDUse.LocalNum == LN_Last &&
269+
// If the two phi defs have the same edge, they must be designated
270+
// for the same succ BB.
271+
getBlockEdge(Top.PInfo) == getBlockEdge(VDUse.PInfo);
272+
}
266273
auto *PHI = dyn_cast<PHINode>(VDUse.U->getUser());
267274
if (!PHI)
268275
return false;

llvm/test/Transforms/SCCP/conditions-ranges.ll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,3 +1547,28 @@ bb2:
15471547
call void @use(i1 %c4)
15481548
ret void
15491549
}
1550+
1551+
define i1 @and_predicate_dominating_phi(i32 %x) {
1552+
; CHECK-LABEL: @and_predicate_dominating_phi(
1553+
; CHECK-NEXT: entry:
1554+
; CHECK-NEXT: [[XGE1:%.*]] = icmp uge i32 [[X:%.*]], 1
1555+
; CHECK-NEXT: [[XLT2:%.*]] = icmp ult i32 [[X]], 2
1556+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[XGE1]], [[XLT2]]
1557+
; CHECK-NEXT: br i1 [[AND]], label [[PHI:%.*]], label [[NOPE:%.*]]
1558+
; CHECK: nope:
1559+
; CHECK-NEXT: br label [[PHI]]
1560+
; CHECK: phi:
1561+
; CHECK-NEXT: ret i1 true
1562+
;
1563+
entry:
1564+
%xge1 = icmp uge i32 %x, 1
1565+
%xlt2 = icmp ult i32 %x, 2
1566+
%and = and i1 %xge1, %xlt2
1567+
br i1 %and, label %phi, label %nope
1568+
nope:
1569+
br label %phi
1570+
phi:
1571+
%res = phi i32 [ %x, %entry ], [ 1, %nope ]
1572+
%ret = icmp uge i32 %res, 1
1573+
ret i1 %ret
1574+
}

llvm/test/Transforms/Util/PredicateInfo/testandor.ll

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,3 +994,30 @@ define void @test_assume_deep_and_tree(i1 %a1) {
994994
call void @foo(i1 %a15)
995995
ret void
996996
}
997+
998+
define i32 @test_and_with_phinode(i32 %x) {
999+
; CHECK-LABEL: @test_and_with_phinode(
1000+
; CHECK-NEXT: entry:
1001+
; CHECK-NEXT: [[XGE1:%.*]] = icmp uge i32 [[X:%.*]], 1
1002+
; CHECK-NEXT: [[XLT2:%.*]] = icmp ult i32 [[X]], 2
1003+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[XGE1]], [[XLT2]]
1004+
; CHECK: [[X_0_1:%.*]] = bitcast i32 [[X]] to i32
1005+
; CHECK: [[X_0_2:%.*]] = bitcast i32 [[X_0_1]] to i32
1006+
; CHECK-NEXT: br i1 [[AND]], label [[PHI:%.*]], label [[NOPE:%.*]]
1007+
; CHECK: nope:
1008+
; CHECK-NEXT: br label [[PHI]]
1009+
; CHECK: phi:
1010+
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[X_0_2]], [[ENTRY:%.*]] ], [ 1, [[NOPE]] ]
1011+
; CHECK-NEXT: ret i32 [[RES]]
1012+
;
1013+
entry:
1014+
%xge1 = icmp uge i32 %x, 1
1015+
%xlt2 = icmp ult i32 %x, 2
1016+
%and = and i1 %xge1, %xlt2
1017+
br i1 %and, label %phi, label %nope
1018+
nope:
1019+
br label %phi
1020+
phi:
1021+
%res = phi i32 [ %x, %entry ], [ 1, %nope ]
1022+
ret i32 %res
1023+
}

0 commit comments

Comments
 (0)