Skip to content

Commit 3023713

Browse files
committed
[ValueTracking] Infer relationship for the select with ICmp
x -nsw y < -C is false when x > y and C >= 0 Alive2 proof for sgt, sge : https://alive2.llvm.org/ce/z/tupvfi Note: It only really makes sense in the context of signed comparison for "X - Y must be positive if X >= Y and no overflow". Fixes #54735
1 parent c41da14 commit 3023713

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9108,6 +9108,17 @@ static std::optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
91089108
if (L0 == R0 && L1 == R1)
91099109
return isImpliedCondMatchingOperands(LPred, RPred);
91109110

9111+
// It only really makes sense in the context of signed comparison for "X - Y
9112+
// must be positive if X >= Y and no overflow".
9113+
// Take SGT as an example: L0:x > L1:y and C >= 0
9114+
// ==> R0:(x -nsw y) < R1:(-C) is false
9115+
if ((LPred == ICmpInst::ICMP_SGT || LPred == ICmpInst::ICMP_SGE) &&
9116+
match(R0, m_NSWSub(m_Specific(L0), m_Specific(L1)))) {
9117+
if (match(R1, m_NonPositive()) &&
9118+
isImpliedCondMatchingOperands(LPred, RPred) == false)
9119+
return false;
9120+
}
9121+
91119122
// L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 <u L1 implies R0 <u R1
91129123
if (L0 == R0 &&
91139124
(LPred == ICmpInst::ICMP_ULT || LPred == ICmpInst::ICMP_UGE) &&

llvm/test/Transforms/InstSimplify/select-icmp.ll

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,7 @@ define i32 @pr54735_sgt(i32 %x, i32 %y) {
4242
; CHECK: cond.true:
4343
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
4444
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[SUB]], 1
45-
; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[SUB]], -1
46-
; CHECK-NEXT: [[ABSCOND:%.*]] = icmp slt i32 [[SUB]], -1
47-
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[ADD]]
48-
; CHECK-NEXT: ret i32 [[ABS]]
45+
; CHECK-NEXT: ret i32 [[ADD]]
4946
; CHECK: cond.end:
5047
; CHECK-NEXT: ret i32 0
5148
;
@@ -74,10 +71,7 @@ define i32 @pr54735_sge(i32 %x, i32 %y) {
7471
; CHECK: cond.true:
7572
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
7673
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[SUB]], 1
77-
; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[SUB]], -1
78-
; CHECK-NEXT: [[ABSCOND:%.*]] = icmp slt i32 [[SUB]], -1
79-
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[ADD]]
80-
; CHECK-NEXT: ret i32 [[ABS]]
74+
; CHECK-NEXT: ret i32 [[ADD]]
8175
; CHECK: cond.end:
8276
; CHECK-NEXT: ret i32 0
8377
;

0 commit comments

Comments
 (0)