Skip to content

[InstSimplify] Canonicalize predicates into strict versions in simplifyICmpInst #151642

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

el-ev
Copy link
Member

@el-ev el-ev commented Aug 1, 2025

@el-ev el-ev requested a review from nikic as a code owner August 1, 2025 05:26
@llvmbot llvmbot added llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:analysis Includes value tracking, cost tables and constant folding llvm:transforms labels Aug 1, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 1, 2025

@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-llvm-analysis

Author: Iris Shi (el-ev)

Changes

Mentioned in https://github.com/llvm/llvm-project/pull/145204/files#r2160245896.


Full diff: https://github.com/llvm/llvm-project/pull/151642.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+11-3)
  • (modified) llvm/test/Transforms/InstSimplify/select-icmp.ll (+1-5)
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 5907e21065331..3e54fce46b8da 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3025,9 +3025,6 @@ static Value *simplifyICmpWithConstant(CmpPredicate Pred, Value *LHS,
         *MulC != 0 && C->srem(*MulC) != 0)))
     return ConstantInt::get(ITy, Pred == ICmpInst::ICMP_NE);
 
-  if (Pred == ICmpInst::ICMP_UGE && C->isOne() && isKnownNonZero(LHS, Q))
-    return ConstantInt::getTrue(ITy);
-
   return nullptr;
 }
 
@@ -3774,6 +3771,17 @@ static Value *simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS,
   if (Value *V = simplifyICmpOfBools(Pred, LHS, RHS, Q))
     return V;
 
+  const APInt *C;
+  if (match(RHS, m_APIntAllowPoison(C))) {
+    if (Pred == ICmpInst::ICMP_UGE && C->isOne()) {
+      Pred = ICmpInst::ICMP_NE;
+      RHS = ConstantInt::get(RHS->getType(), 0);
+    } else if (Pred == ICmpInst::ICMP_SLE && C->isAllOnes()) {
+      Pred = ICmpInst::ICMP_SLT;
+      RHS = ConstantInt::get(RHS->getType(), 0);
+    }
+  }
+
   // TODO: Sink/common this with other potentially expensive calls that use
   //       ValueTracking? See comment below for isKnownNonEqual().
   if (Value *V = simplifyICmpWithZero(Pred, LHS, RHS, Q))
diff --git a/llvm/test/Transforms/InstSimplify/select-icmp.ll b/llvm/test/Transforms/InstSimplify/select-icmp.ll
index 64c0d1d7553fe..0f29998e3fd19 100755
--- a/llvm/test/Transforms/InstSimplify/select-icmp.ll
+++ b/llvm/test/Transforms/InstSimplify/select-icmp.ll
@@ -1,7 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
 
-; TODO: https://alive2.llvm.org/ce/z/3ybZRl
 define i32 @pr54735_slt(i32 %x, i32 %y) {
 ; CHECK-LABEL: @pr54735_slt(
 ; CHECK-NEXT:  entry:
@@ -9,11 +8,8 @@ define i32 @pr54735_slt(i32 %x, i32 %y) {
 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
 ; CHECK:       cond.true:
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], 1
 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[SUB]], -1
-; CHECK-NEXT:    [[ABSCOND:%.*]] = icmp sle i32 [[SUB]], -1
-; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[ABS]]
+; CHECK-NEXT:    ret i32 [[NEG]]
 ; CHECK:       cond.end:
 ; CHECK-NEXT:    ret i32 0
 ;

Pred = ICmpInst::ICMP_SLT;
RHS = ConstantInt::get(RHS->getType(), 0);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use getFlippedStrictnessPredicateAndConstant() to generalize this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that the current implementation provides special handling only for comparisons against zero. I'm not sure if flipping other constant and predicate pairs is profitable. For instance, converting x sgt 0 to x sge -1 causes regressions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What regressions do you see?

The non-strict predicates are the canonical form, so I'd generally expect code to handle them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What regressions do you see?

el-ev@ee94499

@el-ev el-ev changed the title [InstSimplify] Canonicalize X uge 1 to X ne 0 and X sle -1 to X slt 0 in simplifyICmpInst [InstSimplify] Canonicalize predicates into strict versions in simplifyICmpInst Aug 7, 2025
@el-ev el-ev requested a review from nikic August 7, 2025 07:18
@el-ev el-ev force-pushed the users/el-ev/pr145204-comment branch from dbbdf3e to f858afb Compare August 7, 2025 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:analysis Includes value tracking, cost tables and constant folding llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:transforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants