[llvm] (InstCombine) Fold (x | y) > x + y -> x > x + y (PR #164325)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 20 14:49:10 PDT 2025
https://github.com/AZero13 created https://github.com/llvm/llvm-project/pull/164325
Alive2: https://alive2.llvm.org/ce/z/oAoh6c
>From 684ab516eadfe9d4a3f2375272e3aedb71110ded Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Mon, 20 Oct 2025 16:07:34 -0400
Subject: [PATCH 1/2] Pre-commit test (NFC)
---
llvm/test/Transforms/InstCombine/icmp.ll | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 696208b903798..73ee48d2ce44e 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -6240,3 +6240,19 @@ 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: [[OR:%.*]] = or i32 [[Y]], [[X]]
+; CHECK-NEXT: [[ADD:%.*]] = add i32 [[Y]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[OR]], [[ADD]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %or = or i32 %y, %x
+ %add = add i32 %y, %x
+ %cmp = icmp ugt i32 %or, %add
+ ret i1 %cmp
+}
>From 5275ee3e340fa8d1ee1a2364e76ae6bd4eaaa820 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Mon, 20 Oct 2025 16:21:10 -0400
Subject: [PATCH 2/2] Fold (x | y) > x + y -> x > x + y
Alive2: https://alive2.llvm.org/ce/z/oAoh6c
---
.../InstCombine/InstCombineCompares.cpp | 20 +++++++++++++++++++
llvm/test/Transforms/InstCombine/icmp.ll | 19 +++++++++++++++---
2 files changed, 36 insertions(+), 3 deletions(-)
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 73ee48d2ce44e..721c89fac1e44 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -6246,9 +6246,8 @@ entry:
define i1 @uaddo_or(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @uaddo_or(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]]
-; CHECK-NEXT: [[ADD:%.*]] = add i32 [[Y]], [[X]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[OR]], [[ADD]]
+; 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
@@ -6256,3 +6255,17 @@ define i1 @uaddo_or(i32 %x, i32 %y) {
%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
+}
More information about the llvm-commits
mailing list