[PATCH] D159499: [InstCombine] Fold or(phi1,phi2) into or(icmp1,icmp2)
Biplob Mishra via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 11 10:03:59 PDT 2023
bipmis created this revision.
bipmis added reviewers: dmgreen, nikic, RKSimon.
bipmis added projects: LLVM, All.
Herald added a subscriber: StephenFan.
bipmis requested review of this revision.
Herald added a subscriber: wangpc.
For a specific pattern of type or(phi1, phi2), where the other use of phi is an "icmp ne with 0", we can reuse these icmps to form the argument to or. This helps reuse the icmps, reduce or to and, and also bring icmps close to phi for further optimizations.
Alive link https://alive2.llvm.org/ce/z/eAyHWm
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D159499
Files:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/phi.ll
Index: llvm/test/Transforms/InstCombine/phi.ll
===================================================================
--- llvm/test/Transforms/InstCombine/phi.ll
+++ llvm/test/Transforms/InstCombine/phi.ll
@@ -2376,37 +2376,30 @@
; CHECK-NEXT: [[INCDEC_PTR_I]] = getelementptr inbounds i8, ptr [[TEST_0_I]], i64 1
; CHECK-NEXT: br i1 [[CMP1_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
; CHECK: while.end.i:
-; CHECK-NEXT: [[SUB_PTR_LHS_CAST_I:%.*]] = ptrtoint ptr [[TEST_0_I]] to i64
-; CHECK-NEXT: [[SUB_PTR_RHS_CAST_I:%.*]] = ptrtoint ptr [[VAL1]] to i64
-; CHECK-NEXT: [[SUB_PTR_SUB_I:%.*]] = sub i64 [[SUB_PTR_LHS_CAST_I]], [[SUB_PTR_RHS_CAST_I]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne ptr [[TEST_0_I]], [[VAL1]]
; CHECK-NEXT: br label [[_Z3FOOPKC_EXIT]]
; CHECK: _Z3fooPKc.exit:
-; CHECK-NEXT: [[RETVAL_0_I:%.*]] = phi i64 [ [[SUB_PTR_SUB_I]], [[WHILE_END_I]] ], [ 0, [[ENTRY]] ]
+; CHECK-NEXT: [[RETVAL_0_I:%.*]] = phi i1 [ [[TMP1]], [[WHILE_END_I]] ], [ false, [[ENTRY]] ]
; CHECK-NEXT: [[CMP_I10:%.*]] = icmp eq ptr [[VAL2:%.*]], null
; CHECK-NEXT: br i1 [[CMP_I10]], label [[_Z3FOOPKC_EXIT19:%.*]], label [[WHILE_COND_I11:%.*]]
; CHECK: while.cond.i11:
; CHECK-NEXT: [[TEST_0_I12:%.*]] = phi ptr [ [[INCDEC_PTR_I14:%.*]], [[WHILE_COND_I11]] ], [ [[VAL2]], [[_Z3FOOPKC_EXIT]] ]
-; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[TEST_0_I12]], align 1
-; CHECK-NEXT: [[CMP1_NOT_I13:%.*]] = icmp eq i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[TEST_0_I12]], align 1
+; CHECK-NEXT: [[CMP1_NOT_I13:%.*]] = icmp eq i8 [[TMP2]], 0
; CHECK-NEXT: [[INCDEC_PTR_I14]] = getelementptr inbounds i8, ptr [[TEST_0_I12]], i64 1
; CHECK-NEXT: br i1 [[CMP1_NOT_I13]], label [[WHILE_END_I15:%.*]], label [[WHILE_COND_I11]]
; CHECK: while.end.i15:
-; CHECK-NEXT: [[SUB_PTR_LHS_CAST_I16:%.*]] = ptrtoint ptr [[TEST_0_I12]] to i64
-; CHECK-NEXT: [[SUB_PTR_RHS_CAST_I17:%.*]] = ptrtoint ptr [[VAL2]] to i64
-; CHECK-NEXT: [[SUB_PTR_SUB_I18:%.*]] = sub i64 [[SUB_PTR_LHS_CAST_I16]], [[SUB_PTR_RHS_CAST_I17]]
+; CHECK-NEXT: [[TMP3:%.*]] = icmp ne ptr [[TEST_0_I12]], [[VAL2]]
; CHECK-NEXT: br label [[_Z3FOOPKC_EXIT19]]
; CHECK: _Z3fooPKc.exit19:
-; CHECK-NEXT: [[RETVAL_0_I20:%.*]] = phi i64 [ [[SUB_PTR_SUB_I18]], [[WHILE_END_I15]] ], [ 0, [[_Z3FOOPKC_EXIT]] ]
-; CHECK-NEXT: [[TMP2:%.*]] = or i64 [[RETVAL_0_I]], [[RETVAL_0_I20]]
-; CHECK-NEXT: [[OR_COND_NOT:%.*]] = icmp eq i64 [[TMP2]], 0
-; CHECK-NEXT: br i1 [[OR_COND_NOT]], label [[IF_THEN:%.*]], label [[IF_END4:%.*]]
+; CHECK-NEXT: [[RETVAL_0_I20:%.*]] = phi i1 [ [[TMP3]], [[WHILE_END_I15]] ], [ false, [[_Z3FOOPKC_EXIT]] ]
+; CHECK-NEXT: [[TMP4:%.*]] = or i1 [[RETVAL_0_I]], [[RETVAL_0_I20]]
+; CHECK-NEXT: br i1 [[TMP4]], label [[IF_END4:%.*]], label [[IF_THEN:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[DV1:%.*]], [[DV2:%.*]]
; CHECK-NEXT: br label [[CLEANUP:%.*]]
; CHECK: if.end4:
-; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i64 [[RETVAL_0_I20]], 0
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[RETVAL_0_I]], 0
-; CHECK-NEXT: [[OR_COND10:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
+; CHECK-NEXT: [[OR_COND10:%.*]] = and i1 [[RETVAL_0_I]], [[RETVAL_0_I20]]
; CHECK-NEXT: br label [[CLEANUP]]
; CHECK: cleanup:
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i1 [ [[CMP]], [[IF_THEN]] ], [ [[OR_COND10]], [[IF_END4]] ]
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2091,6 +2091,41 @@
if (Value *V = foldICmpOrXorSubChain(Cmp, Or, Builder))
return replaceInstUsesWith(Cmp, V);
+ // icmp eq (or(phi1, phi2)), 0..where there is another use to phi1, phi2 as
+ // "icmp ne phi1, 0" and "icmp ne phi2, 0" We can possibly fold this as icmp
+ // eq (or((icmp ne phi1, 0), (icmp ne phi2, 0))), 0. The above transformation
+ // helps reuse icmps, bring icmp closer to phi and allow other transforms.
+ auto *Phi1 = dyn_cast<PHINode>(OrOp0);
+ auto *Phi2 = dyn_cast<PHINode>(OrOp1);
+ // Phi1 and Phi2 must have multiple users.
+ if (Phi1 && Phi2 && !Phi1->hasOneUser() && !Phi2->hasOneUser()) {
+ ICmpInst::Predicate EqPred;
+ // Check all users of PHI. It should either be the "Or" or a "icmp ne".
+ for (User *U : Phi1->users()) {
+ // Match to specific
+ if (!(U->hasOneUse() &&
+ (match(U, m_Or(m_Specific(OrOp0), m_Specific(OrOp1))) ||
+ (match(U, m_ICmp(EqPred, m_Specific(OrOp0), m_Zero())) &&
+ EqPred == ICmpInst::ICMP_NE))))
+ return nullptr;
+ }
+ for (User *U : Phi2->users()) {
+ // Match to specific
+ if (!(U->hasOneUse() &&
+ (match(U, m_Or(m_Specific(OrOp0), m_Specific(OrOp1))) ||
+ (match(U, m_ICmp(EqPred, m_Specific(OrOp1), m_Zero())) &&
+ EqPred == ICmpInst::ICMP_NE))))
+ return nullptr;
+ }
+ Value *Zero = Constant::getNullValue(OrOp0->getType());
+ Value *Cmp1 = Builder.CreateICmp(EqPred, OrOp0, Zero);
+ Value *Cmp2 = Builder.CreateICmp(EqPred, OrOp1, Zero);
+ Value *newOr = Builder.CreateOr(Cmp1, Cmp2);
+ Cmp1 = Builder.CreateICmp(Pred, newOr,
+ Constant::getNullValue(newOr->getType()));
+ return replaceInstUsesWith(Cmp, Cmp1);
+ }
+
return nullptr;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D159499.556446.patch
Type: text/x-patch
Size: 5536 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230911/72cb2734/attachment.bin>
More information about the llvm-commits
mailing list