[IR] Update `PHINode::removeIncomingValueIf()` to use the swap strategy like `PHINode::removeIncomingValue()`
As suggested in https://github.com/llvm/llvm-project/pull/171963, update PHINode::removeIncomingValueIf() to use the swap strategy too.
@llvm/pr-subscribers-llvm-transforms
@llvm/pr-subscribers-llvm-ir
Author: Mingjie Xu (Enna1)
Changes
As suggested in https://github.com/llvm/llvm-project/pull/171963, update PHINode::removeIncomingValueIf() to use the swap strategy too.
Full diff: https://github.com/llvm/llvm-project/pull/172639.diff
5 Files Affected:
- (modified) llvm/lib/IR/Instructions.cpp (+13-17)
- (modified) llvm/test/CodeGen/WinEH/wineh-no-demotion.ll (+1-1)
- (modified) llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-transform.ll (+6-6)
- (modified) llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll (+12-12)
- (modified) llvm/test/Transforms/PhaseOrdering/AArch64/hoist-load-from-vector-loop.ll (+1-1)
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 573e8a4dd50b7..980693a941384 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -160,26 +160,22 @@ Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) {
void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate,
bool DeletePHIIfEmpty) {
unsigned NumOps = getNumIncomingValues();
- unsigned NewNumOps = 0;
- for (unsigned Idx = 0; Idx < NumOps; ++Idx) {
- if (Predicate(Idx))
- continue;
-
- if (Idx != NewNumOps) {
- setIncomingValue(NewNumOps, getIncomingValue(Idx));
- setIncomingBlock(NewNumOps, getIncomingBlock(Idx));
+ unsigned Idx = 0;
+ while (Idx < NumOps) {
+ if (Predicate(Idx)) {
+ unsigned LastIdx = NumOps - 1;
+ if (Idx != LastIdx) {
+ setIncomingValue(Idx, getIncomingValue(LastIdx));
+ setIncomingBlock(Idx, getIncomingBlock(LastIdx));
+ }
+ getOperandUse(LastIdx).set(nullptr);
+ NumOps--;
+ } else {
+ Idx++;
}
- ++NewNumOps;
}
- if (NewNumOps == NumOps)
- return;
-
- // Remove operands.
- for (unsigned Idx = NewNumOps; Idx < NumOps; ++Idx)
- getOperandUse(Idx).set(nullptr);
-
- setNumHungOffUseOperands(NewNumOps);
+ setNumHungOffUseOperands(NumOps);
// If the PHI node is dead, because it has zero entries, nuke it now.
if (getNumOperands() == 0 && DeletePHIIfEmpty) {
diff --git a/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll b/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll
index 2bfa07221c328..36750f1346114 100644
--- a/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll
@@ -120,7 +120,7 @@ shared:
call void @h(i32 %phi)
unreachable
-; CHECK: %phi = phi i32 [ 0, %right ], [ -1, %right.other ]
+; CHECK: %phi = phi i32 [ -1, %right.other ], [ 0, %right ]
; CHECK: call void @h(i32 %phi)
; CHECK: %phi.for.left = phi i32 [ 1, %left ]
diff --git a/llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-transform.ll b/llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-transform.ll
index 0417d962a6036..ef026b2f2ce28 100644
--- a/llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-transform.ll
+++ b/llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-transform.ll
@@ -42,7 +42,7 @@ define i32 @test1(i32 %num) {
; CHECK-NEXT: br i1 [[CMP_EXIT]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK: for.inc.jt2:
; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT1]], [[SEL_SI_UNFOLD_FALSE_JT2]] ], [ [[COUNT2]], [[CASE1]] ]
-; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ 2, [[CASE1]] ], [ [[DOTSI_UNFOLD_PHI_JT2]], [[SEL_SI_UNFOLD_FALSE_JT2]] ]
+; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ [[DOTSI_UNFOLD_PHI_JT2]], [[SEL_SI_UNFOLD_FALSE_JT2]] ], [ 2, [[CASE1]] ]
; CHECK-NEXT: [[INC_JT2]] = add nsw i32 [[COUNT4]], 1
; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]]
; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2]], label [[FOR_END]]
@@ -112,7 +112,7 @@ define i32 @test2(i32 %init) {
; CHECK-NEXT: [[STATE_1_JT2:%.*]] = phi i32 [ [[STATE_1_BE_SI_UNFOLD_PHI_JT2]], [[STATE_1_BE2_SI_UNFOLD_FALSE_JT2:%.*]] ]
; CHECK-NEXT: br label [[LOOP_2_JT2:%.*]]
; CHECK: loop.1.jt1:
-; CHECK-NEXT: [[STATE_1_JT1:%.*]] = phi i32 [ 1, [[LOOP_1_BACKEDGE]] ], [ 1, [[LOOP_1_BACKEDGE_JT2]] ], [ 1, [[LOOP_1_BACKEDGE_JT4]] ]
+; CHECK-NEXT: [[STATE_1_JT1:%.*]] = phi i32 [ 1, [[LOOP_1_BACKEDGE_JT4]] ], [ 1, [[LOOP_1_BACKEDGE]] ], [ 1, [[LOOP_1_BACKEDGE_JT2]] ]
; CHECK-NEXT: br label [[LOOP_2_JT1:%.*]]
; CHECK: loop.2:
; CHECK-NEXT: [[STATE_2:%.*]] = phi i32 [ [[STATE_1]], [[LOOP_1]] ], [ poison, [[LOOP_2_BACKEDGE:%.*]] ]
@@ -145,7 +145,7 @@ define i32 @test2(i32 %init) {
; CHECK-NEXT: [[STATE_JT0:%.*]] = phi i32 [ [[STATE_2_JT0]], [[LOOP_2_JT0:%.*]] ]
; CHECK-NEXT: br label [[CASE0]]
; CHECK: loop.3.jt3:
-; CHECK-NEXT: [[STATE_JT3:%.*]] = phi i32 [ 3, [[CASE2]] ], [ [[STATE_2_JT3]], [[LOOP_2_JT3:%.*]] ]
+; CHECK-NEXT: [[STATE_JT3:%.*]] = phi i32 [ [[STATE_2_JT3]], [[LOOP_2_JT3:%.*]] ], [ 3, [[CASE2]] ]
; CHECK-NEXT: br label [[CASE3]]
; CHECK: loop.3.jt4:
; CHECK-NEXT: [[STATE_JT4:%.*]] = phi i32 [ [[STATE_2_JT4]], [[LOOP_2_JT4]] ]
@@ -338,8 +338,8 @@ define void @pr106083_invalidBBarg_fold(i1 %cmp1, i1 %cmp2, i1 %not, ptr %d) !pr
; CHECK-NEXT: [[_3_JT1:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI2_JT1]], [[SEL_SI_UNFOLD_FALSE_JT1]] ]
; CHECK-NEXT: br label [[BB8]]
; CHECK: BB7.jt0:
-; CHECK-NEXT: [[D_PROMOTED4_JT0:%.*]] = phi i16 [ 0, [[BB1]] ], [ 1, [[SPEC_SELECT_SI_UNFOLD_FALSE_JT0]] ], [ 1, [[BB7]] ]
-; CHECK-NEXT: [[_3_JT0:%.*]] = phi i32 [ 0, [[BB1]] ], [ [[DOTSI_UNFOLD_PHI_JT0]], [[SPEC_SELECT_SI_UNFOLD_FALSE_JT0]] ], [ [[DOTSI_UNFOLD_PHI1]], [[BB7]] ]
+; CHECK-NEXT: [[D_PROMOTED4_JT0:%.*]] = phi i16 [ 0, [[BB1]] ], [ 1, [[BB7]] ], [ 1, [[SPEC_SELECT_SI_UNFOLD_FALSE_JT0]] ]
+; CHECK-NEXT: [[_3_JT0:%.*]] = phi i32 [ 0, [[BB1]] ], [ [[DOTSI_UNFOLD_PHI1]], [[BB7]] ], [ [[DOTSI_UNFOLD_PHI_JT0]], [[SPEC_SELECT_SI_UNFOLD_FALSE_JT0]] ]
; CHECK-NEXT: br label [[BB1]]
; CHECK: BB1.backedge:
; CHECK-NEXT: br label [[BB1]]
@@ -409,7 +409,7 @@ define void @pr106083_select_dead_uses(i1 %cmp1, i1 %not, ptr %p) {
; CHECK-NEXT: [[_2_JT1:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI2_JT1]], [[SPEC_SELECT_SI_UNFOLD_FALSE_JT1]] ]
; CHECK-NEXT: br label [[DOTLOOPEXIT6]]
; CHECK: select.unfold.jt0:
-; CHECK-NEXT: [[_2_JT0:%.*]] = phi i32 [ 0, [[DOTLOOPEXIT6]] ], [ [[DOTSI_UNFOLD_PHI_JT0]], [[SPEC_SELECT7_SI_UNFOLD_FALSE_JT0]] ], [ [[DOTSI_UNFOLD_PHI1]], [[SELECT_UNFOLD]] ]
+; CHECK-NEXT: [[_2_JT0:%.*]] = phi i32 [ 0, [[DOTLOOPEXIT6]] ], [ [[DOTSI_UNFOLD_PHI1]], [[SELECT_UNFOLD]] ], [ [[DOTSI_UNFOLD_PHI_JT0]], [[SPEC_SELECT7_SI_UNFOLD_FALSE_JT0]] ]
; CHECK-NEXT: br label [[DOTPREHEADER_PREHEADER]]
; CHECK: .preheader.preheader:
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll b/llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll
index d0904ade9bd94..5f0ad6bb1c070 100644
--- a/llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll
+++ b/llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll
@@ -45,7 +45,7 @@ define i32 @test1(i32 %num) {
; CHECK-NEXT: br i1 [[CMP_EXIT]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK: for.inc.jt2:
; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT1]], [[SEL_SI_UNFOLD_FALSE_JT2]] ], [ [[COUNT2]], [[CASE1]] ]
-; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ 2, [[CASE1]] ], [ [[DOTSI_UNFOLD_PHI_JT2]], [[SEL_SI_UNFOLD_FALSE_JT2]] ]
+; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ [[DOTSI_UNFOLD_PHI_JT2]], [[SEL_SI_UNFOLD_FALSE_JT2]] ], [ 2, [[CASE1]] ]
; CHECK-NEXT: [[INC_JT2]] = add nsw i32 [[COUNT4]], 1
; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]]
; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2]], label [[FOR_END]]
@@ -161,19 +161,19 @@ define i32 @test2(i32 %num) {
; CHECK-NEXT: br i1 [[CMP_EXIT]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK: for.inc.jt1:
; CHECK-NEXT: [[COUNT7:%.*]] = phi i32 [ [[COUNT6]], [[STATE1_1_SI_UNFOLD_TRUE_JT1]] ], [ [[COUNT5]], [[STATE2_2_SI_UNFOLD_FALSE_JT1]] ], [ [[COUNT]], [[FOR_BODY]] ]
-; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ 1, [[FOR_BODY]] ], [ [[STATE2_1_SI_UNFOLD_PHI_JT1]], [[STATE2_2_SI_UNFOLD_FALSE_JT1]] ], [ [[DOTSI_UNFOLD_PHI3_JT1]], [[STATE1_1_SI_UNFOLD_TRUE_JT1]] ]
+; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ [[DOTSI_UNFOLD_PHI3_JT1]], [[STATE1_1_SI_UNFOLD_TRUE_JT1]] ], [ [[STATE2_1_SI_UNFOLD_PHI_JT1]], [[STATE2_2_SI_UNFOLD_FALSE_JT1]] ], [ 1, [[FOR_BODY]] ]
; CHECK-NEXT: [[INC_JT1]] = add nsw i32 [[COUNT7]], 1
; CHECK-NEXT: [[CMP_EXIT_JT1:%.*]] = icmp slt i32 [[INC_JT1]], [[NUM]]
; CHECK-NEXT: br i1 [[CMP_EXIT_JT1]], label [[FOR_BODY_JT1]], label [[FOR_END]]
; CHECK: for.inc.jt3:
; CHECK-NEXT: [[COUNT8:%.*]] = phi i32 [ [[COUNT6]], [[STATE1_2_SI_UNFOLD_FALSE_JT3]] ], [ [[COUNT5]], [[CASE2]] ]
-; CHECK-NEXT: [[STATE_NEXT_JT3]] = phi i32 [ 3, [[CASE2]] ], [ [[DOTSI_UNFOLD_PHI2_JT3]], [[STATE1_2_SI_UNFOLD_FALSE_JT3]] ]
+; CHECK-NEXT: [[STATE_NEXT_JT3]] = phi i32 [ [[DOTSI_UNFOLD_PHI2_JT3]], [[STATE1_2_SI_UNFOLD_FALSE_JT3]] ], [ 3, [[CASE2]] ]
; CHECK-NEXT: [[INC_JT3]] = add nsw i32 [[COUNT8]], 1
; CHECK-NEXT: [[CMP_EXIT_JT3:%.*]] = icmp slt i32 [[INC_JT3]], [[NUM]]
; CHECK-NEXT: br i1 [[CMP_EXIT_JT3]], label [[FOR_BODY_JT3]], label [[FOR_END]]
; CHECK: for.inc.jt2:
; CHECK-NEXT: [[COUNT9:%.*]] = phi i32 [ [[COUNT5]], [[STATE2_2_SI_UNFOLD_FALSE_JT2]] ], [ [[COUNT6]], [[STATE1_1_SI_UNFOLD_FALSE_JT2]] ]
-; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ [[DOTSI_UNFOLD_PHI4_JT2]], [[STATE1_1_SI_UNFOLD_FALSE_JT2]] ], [ [[STATE2_1_SI_UNFOLD_PHI_JT2]], [[STATE2_2_SI_UNFOLD_FALSE_JT2]] ]
+; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ [[STATE2_1_SI_UNFOLD_PHI_JT2]], [[STATE2_2_SI_UNFOLD_FALSE_JT2]] ], [ [[DOTSI_UNFOLD_PHI4_JT2]], [[STATE1_1_SI_UNFOLD_FALSE_JT2]] ]
; CHECK-NEXT: [[INC_JT2]] = add nsw i32 [[COUNT9]], 1
; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]]
; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2]], label [[FOR_END]]
@@ -262,7 +262,7 @@ define i32 @test3(i32 %num) {
; CHECK-NEXT: [[SEL_2_SI_UNFOLD_PHI:%.*]] = phi i32 [ poison, [[SEL_2_SI_UNFOLD_FALSE:%.*]] ], [ poison, [[SEL_2_SI_UNFOLD_TRUE]] ]
; CHECK-NEXT: br label [[FOR_INC]]
; CHECK: sel.3.si.unfold.false.jt4:
-; CHECK-NEXT: [[SEL_2_SI_UNFOLD_PHI_JT3:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI1_JT4]], [[SEL_2_SI_UNFOLD_FALSE_JT4]] ], [ [[DOTSI_UNFOLD_PHI_JT3]], [[SEL_2_SI_UNFOLD_TRUE_JT3]] ]
+; CHECK-NEXT: [[SEL_2_SI_UNFOLD_PHI_JT3:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI_JT3]], [[SEL_2_SI_UNFOLD_TRUE_JT3]] ], [ [[DOTSI_UNFOLD_PHI1_JT4]], [[SEL_2_SI_UNFOLD_FALSE_JT4]] ]
; CHECK-NEXT: br label [[FOR_INC_JT3]]
; CHECK: sel.1.si.unfold.true:
; CHECK-NEXT: br i1 [[CMP_1]], label [[FOR_INC]], label [[SEL_1_SI_UNFOLD_FALSE_JT2:%.*]]
@@ -286,13 +286,13 @@ define i32 @test3(i32 %num) {
; CHECK-NEXT: br i1 [[CMP_EXIT_JT3]], label [[FOR_BODY_JT3:%.*]], label [[FOR_END]]
; CHECK: for.inc.jt1:
; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT_JT3]], [[FOR_BODY_JT3]] ], [ [[COUNT5]], [[SEL_1_SI_UNFOLD_TRUE_JT1]] ], [ [[COUNT]], [[FOR_BODY]] ]
-; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ 1, [[FOR_BODY]] ], [ 1, [[FOR_BODY_JT3]] ], [ [[DOTSI_UNFOLD_PHI2_JT1]], [[SEL_1_SI_UNFOLD_TRUE_JT1]] ]
+; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ [[DOTSI_UNFOLD_PHI2_JT1]], [[SEL_1_SI_UNFOLD_TRUE_JT1]] ], [ 1, [[FOR_BODY]] ], [ 1, [[FOR_BODY_JT3]] ]
; CHECK-NEXT: [[INC_JT1]] = add nsw i32 [[COUNT4]], 1
; CHECK-NEXT: [[CMP_EXIT_JT1:%.*]] = icmp slt i32 [[INC_JT1]], [[NUM]]
; CHECK-NEXT: br i1 [[CMP_EXIT_JT1]], label [[FOR_BODY_JT1]], label [[FOR_END]]
; CHECK: for.inc.jt2:
; CHECK-NEXT: [[COUNT7:%.*]] = phi i32 [ [[COUNT6]], [[CASE1]] ], [ [[COUNT5]], [[SEL_1_SI_UNFOLD_FALSE_JT2]] ]
-; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ 2, [[CASE1]] ], [ [[DOTSI_UNFOLD_PHI3_JT2]], [[SEL_1_SI_UNFOLD_FALSE_JT2]] ]
+; CHECK-NEXT: [[STATE_NEXT_JT2]] = phi i32 [ [[DOTSI_UNFOLD_PHI3_JT2]], [[SEL_1_SI_UNFOLD_FALSE_JT2]] ], [ 2, [[CASE1]] ]
; CHECK-NEXT: [[INC_JT2]] = add nsw i32 [[COUNT7]], 1
; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]]
; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2]], label [[FOR_END]]
@@ -406,8 +406,8 @@ define void @pr65222(i32 %flags, i1 %cmp, i1 %tobool.not) {
; CHECK-NEXT: [[OTHER_JT0:%.*]] = phi i32 [ 0, [[TOUNFOLD_SI_UNFOLD_FALSE_JT0]] ]
; CHECK-NEXT: br label [[SW_BB]]
; CHECK: if.end.jt1:
-; CHECK-NEXT: [[UNFOLDED_JT1:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI3_JT1]], [[COND1_SI_UNFOLD_FALSE_JT1]] ], [ [[COND_SI_UNFOLD_PHI_JT1]], [[TOUNFOLD_SI_UNFOLD_FALSE_JT1]] ], [ [[DOTSI_UNFOLD_PHI2]], [[COND1_SI_UNFOLD_TRUE]] ]
-; CHECK-NEXT: [[OTHER_JT1:%.*]] = phi i32 [ 0, [[COND1_SI_UNFOLD_FALSE_JT1]] ], [ 0, [[TOUNFOLD_SI_UNFOLD_FALSE_JT1]] ], [ 0, [[COND1_SI_UNFOLD_TRUE]] ]
+; CHECK-NEXT: [[UNFOLDED_JT1:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI2]], [[COND1_SI_UNFOLD_TRUE]] ], [ [[COND_SI_UNFOLD_PHI_JT1]], [[TOUNFOLD_SI_UNFOLD_FALSE_JT1]] ], [ [[DOTSI_UNFOLD_PHI3_JT1]], [[COND1_SI_UNFOLD_FALSE_JT1]] ]
+; CHECK-NEXT: [[OTHER_JT1:%.*]] = phi i32 [ 0, [[COND1_SI_UNFOLD_TRUE]] ], [ 0, [[TOUNFOLD_SI_UNFOLD_FALSE_JT1]] ], [ 0, [[COND1_SI_UNFOLD_FALSE_JT1]] ]
; CHECK-NEXT: br label [[UNREACHABLE]]
; CHECK: unreachable:
; CHECK-NEXT: unreachable
@@ -462,7 +462,7 @@ define i16 @pr160250() {
; CHECK-NEXT: [[DOT5_SI_UNFOLD_PHI:%.*]] = phi i32 [ poison, [[DOT5_SI_UNFOLD_FALSE:%.*]] ], [ poison, [[DOT5_SI_UNFOLD_TRUE1]] ]
; CHECK-NEXT: br i1 false, label [[SPEC_SELECT_SI_UNFOLD_FALSE1:%.*]], label [[SPEC_SELECT1_SI_UNFOLD_FALSE_JT1:%.*]]
; CHECK: spec.select1.si.unfold.true.jt0:
-; CHECK-NEXT: [[DOT5_SI_UNFOLD_PHI_JT0:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI2_JT0]], [[DOT5_SI_UNFOLD_FALSE_JT0]] ], [ [[DOTSI_UNFOLD_PHI1]], [[DOT5_SI_UNFOLD_TRUE]] ]
+; CHECK-NEXT: [[DOT5_SI_UNFOLD_PHI_JT0:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI1]], [[DOT5_SI_UNFOLD_TRUE]] ], [ [[DOTSI_UNFOLD_PHI2_JT0]], [[DOT5_SI_UNFOLD_FALSE_JT0]] ]
; CHECK-NEXT: br i1 false, label [[SPEC_SELECT_SI_UNFOLD_FALSE:%.*]], label [[SPEC_SELECT1_SI_UNFOLD_FALSE_JT1]]
; CHECK: spec.select1.si.unfold.false:
; CHECK-NEXT: br label [[SPEC_SELECT_SI_UNFOLD_FALSE1]]
@@ -473,7 +473,7 @@ define i16 @pr160250() {
; CHECK-NEXT: [[SPEC_SELECT1_SI_UNFOLD_PHI:%.*]] = phi i32 [ poison, [[SPEC_SELECT1_SI_UNFOLD_FALSE:%.*]] ], [ [[DOT5_SI_UNFOLD_PHI]], [[SPEC_SELECT1_SI_UNFOLD_TRUE1]] ]
; CHECK-NEXT: br label [[CLEANUP87:%.*]]
; CHECK: spec.select.si.unfold.false.jt0:
-; CHECK-NEXT: [[SPEC_SELECT1_SI_UNFOLD_PHI_JT0:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI_JT0]], [[SPEC_SELECT1_SI_UNFOLD_FALSE_JT1]] ], [ [[DOT5_SI_UNFOLD_PHI_JT0]], [[SPEC_SELECT1_SI_UNFOLD_TRUE]] ]
+; CHECK-NEXT: [[SPEC_SELECT1_SI_UNFOLD_PHI_JT0:%.*]] = phi i32 [ [[DOT5_SI_UNFOLD_PHI_JT0]], [[SPEC_SELECT1_SI_UNFOLD_TRUE]] ], [ [[DOTSI_UNFOLD_PHI_JT0]], [[SPEC_SELECT1_SI_UNFOLD_FALSE_JT1]] ]
; CHECK-NEXT: br label [[CLEANUP87_JT0]]
; CHECK: .6.si.unfold.true:
; CHECK-NEXT: br i1 false, label [[CLEANUP87]], label [[DOT6_SI_UNFOLD_FALSE_JT0:%.*]]
@@ -492,7 +492,7 @@ define i16 @pr160250() {
; CHECK-NEXT: i32 1, label [[FOR_COND48_BACKEDGE]]
; CHECK-NEXT: ]
; CHECK: cleanup87.jt0:
-; CHECK-NEXT: [[CLEANUP_DEST_SLOT_3_JT0:%.*]] = phi i32 [ 0, [[FOR_COND48]] ], [ [[DOTSI_UNFOLD_PHI4_JT0]], [[DOT6_SI_UNFOLD_FALSE_JT0]] ], [ [[SPEC_SELECT1_SI_UNFOLD_PHI_JT0]], [[SPEC_SELECT_SI_UNFOLD_FALSE]] ], [ [[DOTSI_UNFOLD_PHI3]], [[DOT6_SI_UNFOLD_TRUE]] ]
+; CHECK-NEXT: [[CLEANUP_DEST_SLOT_3_JT0:%.*]] = phi i32 [ 0, [[FOR_COND48]] ], [ [[DOTSI_UNFOLD_PHI3]], [[DOT6_SI_UNFOLD_TRUE]] ], [ [[SPEC_SELECT1_SI_UNFOLD_PHI_JT0]], [[SPEC_SELECT_SI_UNFOLD_FALSE]] ], [ [[DOTSI_UNFOLD_PHI4_JT0]], [[DOT6_SI_UNFOLD_FALSE_JT0]] ]
; CHECK-NEXT: br label [[FOR_COND48_BACKEDGE]]
; CHECK: for.cond48.backedge:
; CHECK-NEXT: br label [[FOR_COND48]]
diff --git a/llvm/test/Transforms/PhaseOrdering/AArch64/hoist-load-from-vector-loop.ll b/llvm/test/Transforms/PhaseOrdering/AArch64/hoist-load-from-vector-loop.ll
index 66f238d7cbdec..c17b15138329c 100644
--- a/llvm/test/Transforms/PhaseOrdering/AArch64/hoist-load-from-vector-loop.ll
+++ b/llvm/test/Transforms/PhaseOrdering/AArch64/hoist-load-from-vector-loop.ll
@@ -59,7 +59,7 @@ define void @hoist_invariant_load(ptr %invariant_ptr, i64 %num_elements, ptr %ar
; CHECK-NEXT: [[TMP20:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
; CHECK-NEXT: br i1 [[TMP20]], label %[[LOOP_LATCH_PREHEADER6]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
; CHECK: [[LOOP_LATCH_PREHEADER6]]:
-; CHECK-NEXT: [[I2_PH:%.*]] = phi i64 [ 0, %[[LOOP_LATCH_PREHEADER]] ], [ 0, %[[VECTOR_MEMCHECK]] ], [ [[N_VEC]], %[[VECTOR_BODY]] ]
+; CHECK-NEXT: [[I2_PH:%.*]] = phi i64 [ 0, %[[VECTOR_MEMCHECK]] ], [ 0, %[[LOOP_LATCH_PREHEADER]] ], [ [[N_VEC]], %[[VECTOR_BODY]] ]
; CHECK-NEXT: br label %[[LOOP_LATCH:.*]]
; CHECK: [[LOOP_LATCH]]:
; CHECK-NEXT: [[I3:%.*]] = phi i64 [ [[I_NEXT:%.*]], %[[LOOP_LATCH]] ], [ [[I2_PH]], %[[LOOP_LATCH_PREHEADER6]] ]
:penguin: Linux x64 Test Results
- 187577 tests passed
- 4972 tests skipped
:white_check_mark: The build succeeded and all tests passed.
:window: Windows x64 Test Results
- 128737 tests passed
- 2824 tests skipped
:white_check_mark: The build succeeded and all tests passed.
I'm sorry if this is obvious, but is this swap generally correct? I think this works so long as Predicate is either value-based (using Idx to access the corresponding incoming value) or all incoming values to remove are last in Idx order. But, for example, if someone did PN->removeIncomingValueIf([](unsigned Idx) { return Idx == 0; }) to remove only the first incoming value, I believe the new code would end up removing all incoming values of the Phi instead. Is this expected?
Yes, the general expectation is that the predicate is value based (as in, based on incoming value and incoming BB).
It would probably be clearer if the predicate was passed a Use & rather than Idx.
Though I guess we could make this a reverse loop if there is a use case for a purely index based predicate?
That makes sense, thanks for the explanation. I don't have a use case for index-based predicates; I came across this PR while examining a few performance regressions that were flagged recently, but I'll continue looking into them next year. :) I believe there are a couple of uses of index-based predicates in LoopSimplify and LoopUtils, but they appear to be correct since they use Idx to remove all incoming values except the first.
But, for example, if someone did PN->removeIncomingValueIf([](unsigned Idx) { return Idx == 0; }) to remove only the first incoming value, I believe the new code would end up removing all incoming values of the Phi instead.
Thanks for pointing this. @rj-jesus
I believe there are a couple of uses of index-based predicates in LoopSimplify and LoopUtils
I checked the uses of removeIncomingValueIf().
LoopSimplify and LoopUtils use index-based predicates:
- https://github.com/llvm/llvm-project/blob/8c5a0f74a12d69d2fb7d6ed59f91759f18273bcd/llvm/lib/Transforms/Utils/LoopSimplify.cpp#L429
- https://github.com/llvm/llvm-project/blob/8c5a0f74a12d69d2fb7d6ed59f91759f18273bcd/llvm/lib/Transforms/Utils/LoopUtils.cpp#L562
Except LoopSimplify and LoopUtils, all other uses of PHINode::removeIncomingValueIf() use incoming block based predicate.
Though I guess we could make this a reverse loop if there is a use case for a purely index based predicate?
Send https://github.com/llvm/llvm-project/pull/173444 to use a reverse loop in removeIncomingValueIf().