Skip to content

Conversation

@AZero13
Copy link
Contributor

@AZero13 AZero13 commented Oct 20, 2025

@AZero13 AZero13 requested a review from nikic as a code owner October 20, 2025 21:49
@llvmbot llvmbot added llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:transforms labels Oct 20, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 20, 2025

@llvm/pr-subscribers-llvm-transforms

Author: AZero13 (AZero13)

Changes

Alive2: https://alive2.llvm.org/ce/z/oAoh6c


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp (+20)
  • (modified) llvm/test/Transforms/InstCombine/icmp.ll (+29)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index fba1ccf2c8c9b..212a47af2cd20 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -7855,6 +7855,26 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
       }
     }
 
+    // Transform (x | y) > x + y into x > x + y
+    Value *OrLHS, *OrRHS, *AddLHS, *AddRHS;
+    if (match(Op0, m_Or(m_Value(OrLHS), m_Value(OrRHS))) &&
+        match(Op1, m_Add(m_Value(AddLHS), m_Value(AddRHS))) &&
+        ((OrLHS == AddLHS && OrRHS == AddRHS) ||
+         (OrLHS == AddRHS && OrRHS == AddLHS))) {
+      // Replace (x | y) with x in the comparison
+      replaceOperand(I, 0, AddLHS);
+      return &I;
+    }
+
+    if (match(Op0, m_Add(m_Value(AddLHS), m_Value(AddRHS))) &&
+        match(Op1, m_Or(m_Value(OrLHS), m_Value(OrRHS))) &&
+        ((AddLHS == OrLHS && AddRHS == OrRHS) ||
+         (AddLHS == OrRHS && AddRHS == OrLHS))) {
+      // Replace (x | y) with x in the comparison
+      replaceOperand(I, 1, AddLHS);
+      return &I;
+    }
+
     Instruction *AddI = nullptr;
     if (match(&I, m_UAddWithOverflow(m_Value(X), m_Value(Y),
                                      m_Instruction(AddI))) &&
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 696208b903798..721c89fac1e44 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -6240,3 +6240,32 @@ entry:
   %cmp = icmp ult i8 %p0, %p1
   ret i1 %cmp
 }
+
+; Transform (x | y) > x + y into x > x + y
+; This is valid because (x | y) >= x always, so (x | y) > x + y is equivalent to x > x + y
+define i1 @uaddo_or(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @uaddo_or(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], -1
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %or = or i32 %y, %x
+  %add = add i32 %y, %x
+  %cmp = icmp ugt i32 %or, %add
+  ret i1 %cmp
+}
+
+; Transform x + y < (x | y) into x + y < x (equivalent to x > x + y)
+define i1 @uaddo_or_reverse(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @uaddo_or_reverse(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y]], -1
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %add = add i32 %y, %x
+  %or = or i32 %y, %x
+  %cmp = icmp ult i32 %add, %or
+  ret i1 %cmp
+}

@nikic
Copy link
Contributor

nikic commented Oct 22, 2025

No hits on llvm-opt-benchmark.

@AZero13
Copy link
Contributor Author

AZero13 commented Oct 23, 2025

Well, it was worth a shot.

@AZero13 AZero13 closed this Oct 23, 2025
@AZero13 AZero13 deleted the ov2 branch October 23, 2025 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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