Skip to content

Commit 5275ee3

Browse files
committed
Fold (x | y) > x + y -> x > x + y
Alive2: https://alive2.llvm.org/ce/z/oAoh6c
1 parent 684ab51 commit 5275ee3

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7855,6 +7855,26 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
78557855
}
78567856
}
78577857

7858+
// Transform (x | y) > x + y into x > x + y
7859+
Value *OrLHS, *OrRHS, *AddLHS, *AddRHS;
7860+
if (match(Op0, m_Or(m_Value(OrLHS), m_Value(OrRHS))) &&
7861+
match(Op1, m_Add(m_Value(AddLHS), m_Value(AddRHS))) &&
7862+
((OrLHS == AddLHS && OrRHS == AddRHS) ||
7863+
(OrLHS == AddRHS && OrRHS == AddLHS))) {
7864+
// Replace (x | y) with x in the comparison
7865+
replaceOperand(I, 0, AddLHS);
7866+
return &I;
7867+
}
7868+
7869+
if (match(Op0, m_Add(m_Value(AddLHS), m_Value(AddRHS))) &&
7870+
match(Op1, m_Or(m_Value(OrLHS), m_Value(OrRHS))) &&
7871+
((AddLHS == OrLHS && AddRHS == OrRHS) ||
7872+
(AddLHS == OrRHS && AddRHS == OrLHS))) {
7873+
// Replace (x | y) with x in the comparison
7874+
replaceOperand(I, 1, AddLHS);
7875+
return &I;
7876+
}
7877+
78587878
Instruction *AddI = nullptr;
78597879
if (match(&I, m_UAddWithOverflow(m_Value(X), m_Value(Y),
78607880
m_Instruction(AddI))) &&

llvm/test/Transforms/InstCombine/icmp.ll

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6246,13 +6246,26 @@ entry:
62466246
define i1 @uaddo_or(i32 %x, i32 %y) {
62476247
; CHECK-LABEL: define i1 @uaddo_or(
62486248
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
6249-
; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]]
6250-
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[Y]], [[X]]
6251-
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[OR]], [[ADD]]
6249+
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y]], -1
6250+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X]], [[TMP1]]
62526251
; CHECK-NEXT: ret i1 [[CMP]]
62536252
;
62546253
%or = or i32 %y, %x
62556254
%add = add i32 %y, %x
62566255
%cmp = icmp ugt i32 %or, %add
62576256
ret i1 %cmp
62586257
}
6258+
6259+
; Transform x + y < (x | y) into x + y < x (equivalent to x > x + y)
6260+
define i1 @uaddo_or_reverse(i32 %x, i32 %y) {
6261+
; CHECK-LABEL: define i1 @uaddo_or_reverse(
6262+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
6263+
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y]], -1
6264+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X]], [[TMP1]]
6265+
; CHECK-NEXT: ret i1 [[CMP]]
6266+
;
6267+
%add = add i32 %y, %x
6268+
%or = or i32 %y, %x
6269+
%cmp = icmp ult i32 %add, %or
6270+
ret i1 %cmp
6271+
}

0 commit comments

Comments
 (0)