Skip to content

Commit 186c907

Browse files
authored
[InstCombine] Expand redundant phi cycle elimination (#67968)
There is a combine in instcombine that will look for phi cycles that only have a single incoming value: ``` %0 = phi i64 [ %3, %exit ], [ %othervalue, %preheader ] %3 = phi i64 [ %0, %body ], [ %othervalue, %body2 ] ``` This currently doesn't handle if %othervalue is a phi though, as the algorithm will recurse into the phi and fail with multiple incoming values. This adjusts the algorithm, not requiring the initial value to be found immediately, allowing it to be set to the value of one of the phis that would otherwise fail due to having multiple input values.
1 parent c2ff180 commit 186c907

File tree

2 files changed

+76
-17
lines changed

2 files changed

+76
-17
lines changed

llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -996,8 +996,8 @@ static bool isDeadPHICycle(PHINode *PN,
996996
/// Return true if this phi node is always equal to NonPhiInVal.
997997
/// This happens with mutually cyclic phi nodes like:
998998
/// z = some value; x = phi (y, z); y = phi (x, z)
999-
static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal,
1000-
SmallPtrSetImpl<PHINode*> &ValueEqualPHIs) {
999+
static bool PHIsEqualValue(PHINode *PN, Value *&NonPhiInVal,
1000+
SmallPtrSetImpl<PHINode *> &ValueEqualPHIs) {
10011001
// See if we already saw this PHI node.
10021002
if (!ValueEqualPHIs.insert(PN).second)
10031003
return true;
@@ -1010,8 +1010,11 @@ static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal,
10101010
// the value.
10111011
for (Value *Op : PN->incoming_values()) {
10121012
if (PHINode *OpPN = dyn_cast<PHINode>(Op)) {
1013-
if (!PHIsEqualValue(OpPN, NonPhiInVal, ValueEqualPHIs))
1014-
return false;
1013+
if (!PHIsEqualValue(OpPN, NonPhiInVal, ValueEqualPHIs)) {
1014+
if (NonPhiInVal)
1015+
return false;
1016+
NonPhiInVal = OpPN;
1017+
}
10151018
} else if (Op != NonPhiInVal)
10161019
return false;
10171020
}
@@ -1478,33 +1481,35 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
14781481
// z = some value; x = phi (y, z); y = phi (x, z)
14791482
// where the phi nodes don't necessarily need to be in the same block. Do a
14801483
// quick check to see if the PHI node only contains a single non-phi value, if
1481-
// so, scan to see if the phi cycle is actually equal to that value.
1484+
// so, scan to see if the phi cycle is actually equal to that value. If the
1485+
// phi has no non-phi values then allow the "NonPhiInVal" to be set later if
1486+
// one of the phis itself does not have a single input.
14821487
{
14831488
unsigned InValNo = 0, NumIncomingVals = PN.getNumIncomingValues();
14841489
// Scan for the first non-phi operand.
14851490
while (InValNo != NumIncomingVals &&
14861491
isa<PHINode>(PN.getIncomingValue(InValNo)))
14871492
++InValNo;
14881493

1489-
if (InValNo != NumIncomingVals) {
1490-
Value *NonPhiInVal = PN.getIncomingValue(InValNo);
1494+
Value *NonPhiInVal =
1495+
InValNo != NumIncomingVals ? PN.getIncomingValue(InValNo) : nullptr;
14911496

1492-
// Scan the rest of the operands to see if there are any conflicts, if so
1493-
// there is no need to recursively scan other phis.
1497+
// Scan the rest of the operands to see if there are any conflicts, if so
1498+
// there is no need to recursively scan other phis.
1499+
if (NonPhiInVal)
14941500
for (++InValNo; InValNo != NumIncomingVals; ++InValNo) {
14951501
Value *OpVal = PN.getIncomingValue(InValNo);
14961502
if (OpVal != NonPhiInVal && !isa<PHINode>(OpVal))
14971503
break;
14981504
}
14991505

1500-
// If we scanned over all operands, then we have one unique value plus
1501-
// phi values. Scan PHI nodes to see if they all merge in each other or
1502-
// the value.
1503-
if (InValNo == NumIncomingVals) {
1504-
SmallPtrSet<PHINode*, 16> ValueEqualPHIs;
1505-
if (PHIsEqualValue(&PN, NonPhiInVal, ValueEqualPHIs))
1506-
return replaceInstUsesWith(PN, NonPhiInVal);
1507-
}
1506+
// If we scanned over all operands, then we have one unique value plus
1507+
// phi values. Scan PHI nodes to see if they all merge in each other or
1508+
// the value.
1509+
if (InValNo == NumIncomingVals) {
1510+
SmallPtrSet<PHINode *, 16> ValueEqualPHIs;
1511+
if (PHIsEqualValue(&PN, NonPhiInVal, ValueEqualPHIs))
1512+
return replaceInstUsesWith(PN, NonPhiInVal);
15081513
}
15091514
}
15101515

llvm/test/Transforms/InstCombine/phi.ll

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,60 @@ end:
837837
ret i1 %z
838838
}
839839

840+
; Same as above, but the input is also a phi
841+
define i1 @test25b(i1 %ci, i64 %ai, i64 %bi) {
842+
; CHECK-LABEL: @test25b(
843+
; CHECK-NEXT: entry:
844+
; CHECK-NEXT: br i1 [[CI:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
845+
; CHECK: then:
846+
; CHECK-NEXT: br label [[ELSE]]
847+
; CHECK: else:
848+
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[AI:%.*]], [[ENTRY:%.*]] ], [ [[BI:%.*]], [[THEN]] ]
849+
; CHECK-NEXT: [[B:%.*]] = call i1 @test25a()
850+
; CHECK-NEXT: br i1 [[B]], label [[ONE:%.*]], label [[TWO:%.*]]
851+
; CHECK: one:
852+
; CHECK-NEXT: [[C:%.*]] = call i1 @test25a()
853+
; CHECK-NEXT: br i1 [[C]], label [[TWO]], label [[END:%.*]]
854+
; CHECK: two:
855+
; CHECK-NEXT: [[D:%.*]] = call i1 @test25a()
856+
; CHECK-NEXT: br i1 [[D]], label [[ONE]], label [[END]]
857+
; CHECK: end:
858+
; CHECK-NEXT: [[G:%.*]] = inttoptr i64 [[I]] to ptr
859+
; CHECK-NEXT: store i32 10, ptr [[G]], align 4
860+
; CHECK-NEXT: [[Z:%.*]] = call i1 @test25a()
861+
; CHECK-NEXT: ret i1 [[Z]]
862+
;
863+
entry:
864+
br i1 %ci, label %then, label %else
865+
866+
then:
867+
br label %else
868+
869+
else:
870+
%i = phi i64 [ %ai, %entry ], [ %bi, %then ]
871+
%b = call i1 @test25a()
872+
br i1 %b, label %one, label %two
873+
874+
one:
875+
%x = phi i64 [%y, %two], [%i, %else]
876+
%c = call i1 @test25a()
877+
br i1 %c, label %two, label %end
878+
879+
two:
880+
%y = phi i64 [%x, %one], [%i, %else]
881+
%d = call i1 @test25a()
882+
br i1 %d, label %one, label %end
883+
884+
end:
885+
%f = phi i64 [ %x, %one], [%y, %two]
886+
; Change the %f to %i, and the optimizer suddenly becomes a lot smarter
887+
; even though %f must equal %i at this point
888+
%g = inttoptr i64 %f to ptr
889+
store i32 10, ptr %g
890+
%z = call i1 @test25a()
891+
ret i1 %z
892+
}
893+
840894
declare i1 @test26a()
841895

842896
define i1 @test26(i32 %n) {

0 commit comments

Comments
 (0)