Skip to content

Commit 92b826f

Browse files
committed
[InstCombine] Eliminate icmp+zext pairs over phis more aggressively
1 parent d68ea31 commit 92b826f

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,12 +1822,29 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN,
18221822
continue;
18231823
}
18241824

1825-
// If the only use of phi is comparing it with a constant then we can
1826-
// put this comparison in the incoming BB directly after a ucmp/scmp call
1827-
// because we know that it will simplify to a single icmp.
1828-
const APInt *Ignored;
1829-
if (isa<CmpIntrinsic>(InVal) && InVal->hasOneUser() &&
1830-
match(&I, m_ICmp(m_Specific(PN), m_APInt(Ignored)))) {
1825+
// Handle some cases that can't be fully simplified, but where we know that
1826+
// the two instructions will fold into one.
1827+
auto WillFold = [&]() {
1828+
if (!InVal->hasOneUser())
1829+
return false;
1830+
1831+
// icmp of ucmp/scmp with constant will fold to icmp.
1832+
const APInt *Ignored;
1833+
if (isa<CmpIntrinsic>(InVal) &&
1834+
match(&I, m_ICmp(m_Specific(PN), m_APInt(Ignored))))
1835+
return true;
1836+
1837+
// icmp eq zext(bool), 0 will fold to !bool.
1838+
if (isa<ZExtInst>(InVal) &&
1839+
cast<ZExtInst>(InVal)->getSrcTy()->isIntOrIntVectorTy(1) &&
1840+
match(&I,
1841+
m_SpecificICmp(ICmpInst::ICMP_EQ, m_Specific(PN), m_Zero())))
1842+
return true;
1843+
1844+
return false;
1845+
};
1846+
1847+
if (WillFold()) {
18311848
OpsToMoveUseToIncomingBB.push_back(i);
18321849
NewPhiValues.push_back(nullptr);
18331850
continue;

llvm/test/Transforms/InstCombine/phi.ll

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,13 +2828,13 @@ define i1 @test_zext_icmp_eq_0(i1 %a, i1 %b, i32 %c) {
28282828
; CHECK-NEXT: entry:
28292829
; CHECK-NEXT: br i1 [[A:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
28302830
; CHECK: if:
2831-
; CHECK-NEXT: [[B_EXT:%.*]] = zext i1 [[B:%.*]] to i32
2831+
; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[B:%.*]], true
28322832
; CHECK-NEXT: br label [[JOIN:%.*]]
28332833
; CHECK: else:
2834+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[C:%.*]], 0
28342835
; CHECK-NEXT: br label [[JOIN]]
28352836
; CHECK: join:
2836-
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[B_EXT]], [[IF]] ], [ [[C:%.*]], [[ELSE]] ]
2837-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[PHI]], 0
2837+
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ [[TMP0]], [[IF]] ], [ [[TMP1]], [[ELSE]] ]
28382838
; CHECK-NEXT: ret i1 [[CMP]]
28392839
;
28402840
entry:
@@ -2916,10 +2916,9 @@ define i1 @test_zext_icmp_eq_0_loop(i1 %c, i1 %b) {
29162916
; CHECK-NEXT: entry:
29172917
; CHECK-NEXT: br label [[LOOP:%.*]]
29182918
; CHECK: loop:
2919-
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[EXT:%.*]], [[LOOP]] ]
2920-
; CHECK-NEXT: [[X:%.*]] = icmp eq i32 [[PHI]], 0
2919+
; CHECK-NEXT: [[X:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ]
29212920
; CHECK-NEXT: [[Y:%.*]] = and i1 [[X]], [[B:%.*]]
2922-
; CHECK-NEXT: [[EXT]] = zext i1 [[Y]] to i32
2921+
; CHECK-NEXT: [[TMP0]] = xor i1 [[Y]], true
29232922
; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP]], label [[EXIT:%.*]]
29242923
; CHECK: exit:
29252924
; CHECK-NEXT: ret i1 [[X]]

0 commit comments

Comments
 (0)