[llvm] 5f8c2b8 - [InstCombine] limit icmp fold with sub if other sub user is a phi

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 2 16:33:17 PDT 2022


Author: Sanjay Patel
Date: 2022-04-02T19:23:42-04:00
New Revision: 5f8c2b884d4288617138114ebd2fdb235452c8ce

URL: https://github.com/llvm/llvm-project/commit/5f8c2b884d4288617138114ebd2fdb235452c8ce
DIFF: https://github.com/llvm/llvm-project/commit/5f8c2b884d4288617138114ebd2fdb235452c8ce.diff

LOG: [InstCombine] limit icmp fold with sub if other sub user is a phi

This is a hacky fix for:
https://github.com/llvm/llvm-project/issues/54558

As discussed there, codegen regressed when we opened up this transform
to allow extra uses ( 61580d0949fd3465 ), and it's not clear how to
undo the transforms at the later stage of compilation.

As noted in the code comments, there's a set of remaining folds that
are still limited to one-use, so we can try harder to refine and
expand the limitations on these folds, but it's likely to be an
up-and-down battle as we find and overcome similar regressions.

Differential Revision: https://reviews.llvm.org/D122909

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/icmp-sub.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 4c34d56526ffe..39c20ec06ca29 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2593,13 +2593,19 @@ Instruction *InstCombinerImpl::foldICmpSubConstant(ICmpInst &Cmp,
 
   // X - Y == 0 --> X == Y.
   // X - Y != 0 --> X != Y.
-  if (Cmp.isEquality() && C.isZero())
+  // TODO: We allow this with multiple uses as long as the other uses are not
+  //       in phis. The phi use check is guarding against a codegen regression
+  //       for a loop test. If the backend could undo this (and possibly
+  //       subsequent transforms), we would not need this hack.
+  if (Cmp.isEquality() && C.isZero() &&
+      none_of((Sub->users()), [](const User *U) { return isa<PHINode>(U); }))
     return new ICmpInst(Pred, X, Y);
 
   // The following transforms are only worth it if the only user of the subtract
   // is the icmp.
   // TODO: This is an artificial restriction for all of the transforms below
-  //       that only need a single replacement icmp.
+  //       that only need a single replacement icmp. Can these use the phi test
+  //       like the transform above here?
   if (!Sub->hasOneUse())
     return nullptr;
 

diff  --git a/llvm/test/Transforms/InstCombine/icmp-sub.ll b/llvm/test/Transforms/InstCombine/icmp-sub.ll
index 026560d5c6da2..74d002fefda8d 100644
--- a/llvm/test/Transforms/InstCombine/icmp-sub.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-sub.ll
@@ -502,7 +502,7 @@ define i32 @sub_eq_zero_select(i32 %a, i32 %b, i32* %p) {
   ret i32 %sel
 }
 
-; TODO: Replacing the "SUB == 0" regresses codegen, and it may be hard to recover from that.
+; Replacing the "SUB == 0" regresses codegen, and it may be hard to recover from that.
 
 declare i32 @llvm.umin.i32(i32, i32)
 
@@ -515,7 +515,7 @@ define void @PR54558_reduced(i32 %arg) {
 ; CHECK-NEXT:    [[MIN:%.*]] = tail call i32 @llvm.umin.i32(i32 [[PHI_OUTER]], i32 43)
 ; CHECK-NEXT:    call void @use(i32 [[MIN]])
 ; CHECK-NEXT:    [[SUB]] = sub i32 [[PHI_OUTER]], [[MIN]]
-; CHECK-NEXT:    [[COND_OUTER:%.*]] = icmp ult i32 [[PHI_OUTER]], 44
+; CHECK-NEXT:    [[COND_OUTER:%.*]] = icmp eq i32 [[SUB]], 0
 ; CHECK-NEXT:    br i1 [[COND_OUTER]], label [[BB_EXIT:%.*]], label [[BB_LOOP]]
 ; CHECK:       bb_exit:
 ; CHECK-NEXT:    ret void
@@ -535,6 +535,8 @@ bb_exit:
   ret void
 }
 
+; TODO: It might be ok to replace the "SUB == 0" in this example if codegen can invert it.
+
 define void @PR54558_reduced_more(i32 %x, i32 %y) {
 ; CHECK-LABEL: @PR54558_reduced_more(
 ; CHECK-NEXT:  bb_entry:
@@ -542,7 +544,7 @@ define void @PR54558_reduced_more(i32 %x, i32 %y) {
 ; CHECK:       bb_loop:
 ; CHECK-NEXT:    [[PHI_OUTER:%.*]] = phi i32 [ [[SUB:%.*]], [[BB_LOOP]] ], [ [[X:%.*]], [[BB_ENTRY:%.*]] ]
 ; CHECK-NEXT:    [[SUB]] = sub i32 [[PHI_OUTER]], [[Y:%.*]]
-; CHECK-NEXT:    [[COND_OUTER:%.*]] = icmp eq i32 [[PHI_OUTER]], [[Y]]
+; CHECK-NEXT:    [[COND_OUTER:%.*]] = icmp eq i32 [[SUB]], 0
 ; CHECK-NEXT:    br i1 [[COND_OUTER]], label [[BB_EXIT:%.*]], label [[BB_LOOP]]
 ; CHECK:       bb_exit:
 ; CHECK-NEXT:    ret void


        


More information about the llvm-commits mailing list