Skip to content

Commit 5a9eeca

Browse files
committed
VT: teach isImpliedCondOperands about samesign
isImpliedCondICmps() and its callers in ValueTracking can greatly benefit from being taught about samesign. As a first step, teach one caller, namely isImpliedCondOperands(). Very minimal changes are required for this, as CmpPredicate::getMatching() does most of the work.
1 parent fc6aa3d commit 5a9eeca

File tree

2 files changed

+17
-35
lines changed

2 files changed

+17
-35
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9335,8 +9335,8 @@ static bool isTruePredicate(CmpInst::Predicate Pred, const Value *LHS,
93359335
/// Return true if "icmp Pred BLHS BRHS" is true whenever "icmp Pred
93369336
/// ALHS ARHS" is true. Otherwise, return std::nullopt.
93379337
static std::optional<bool>
9338-
isImpliedCondOperands(CmpInst::Predicate Pred, const Value *ALHS,
9339-
const Value *ARHS, const Value *BLHS, const Value *BRHS) {
9338+
isImpliedCondOperands(CmpPredicate Pred, const Value *ALHS, const Value *ARHS,
9339+
const Value *BLHS, const Value *BRHS) {
93409340
switch (Pred) {
93419341
default:
93429342
return std::nullopt;
@@ -9405,36 +9405,34 @@ static std::optional<bool> isImpliedCondCommonOperandWithCR(
94059405
/// Return true if LHS implies RHS (expanded to its components as "R0 RPred R1")
94069406
/// is true. Return false if LHS implies RHS is false. Otherwise, return
94079407
/// std::nullopt if we can't infer anything.
9408-
static std::optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
9409-
CmpInst::Predicate RPred,
9410-
const Value *R0, const Value *R1,
9411-
const DataLayout &DL,
9412-
bool LHSIsTrue) {
9408+
static std::optional<bool>
9409+
isImpliedCondICmps(const ICmpInst *LHS, CmpPredicate RPred, const Value *R0,
9410+
const Value *R1, const DataLayout &DL, bool LHSIsTrue) {
94139411
Value *L0 = LHS->getOperand(0);
94149412
Value *L1 = LHS->getOperand(1);
94159413

94169414
// The rest of the logic assumes the LHS condition is true. If that's not the
94179415
// case, invert the predicate to make it so.
9418-
CmpInst::Predicate LPred =
9419-
LHSIsTrue ? LHS->getPredicate() : LHS->getInversePredicate();
9416+
CmpPredicate LPred =
9417+
LHSIsTrue ? LHS->getCmpPredicate() : LHS->getInverseCmpPredicate();
94209418

94219419
// We can have non-canonical operands, so try to normalize any common operand
94229420
// to L0/R0.
94239421
if (L0 == R1) {
94249422
std::swap(R0, R1);
9425-
RPred = ICmpInst::getSwappedPredicate(RPred);
9423+
RPred = ICmpInst::getSwappedCmpPredicate(RPred);
94269424
}
94279425
if (R0 == L1) {
94289426
std::swap(L0, L1);
9429-
LPred = ICmpInst::getSwappedPredicate(LPred);
9427+
LPred = ICmpInst::getSwappedCmpPredicate(LPred);
94309428
}
94319429
if (L1 == R1) {
94329430
// If we have L0 == R0 and L1 == R1, then make L1/R1 the constants.
94339431
if (L0 != R0 || match(L0, m_ImmConstant())) {
94349432
std::swap(L0, L1);
9435-
LPred = ICmpInst::getSwappedPredicate(LPred);
9433+
LPred = ICmpInst::getSwappedCmpPredicate(LPred);
94369434
std::swap(R0, R1);
9437-
RPred = ICmpInst::getSwappedPredicate(RPred);
9435+
RPred = ICmpInst::getSwappedCmpPredicate(RPred);
94389436
}
94399437
}
94409438

@@ -9493,8 +9491,8 @@ static std::optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
94939491
match(L0, m_c_Add(m_Specific(L1), m_Specific(R1))))
94949492
return CmpPredicate::getMatching(LPred, RPred).has_value();
94959493

9496-
if (LPred == RPred)
9497-
return isImpliedCondOperands(LPred, L0, L1, R0, R1);
9494+
if (auto P = CmpPredicate::getMatching(LPred, RPred))
9495+
return isImpliedCondOperands(*P, L0, L1, R0, R1);
94989496

94999497
return std::nullopt;
95009498
}

llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@
44
define i1 @incr_sle(i32 %i, i32 %len) {
55
; CHECK-LABEL: define i1 @incr_sle(
66
; CHECK-SAME: i32 [[I:%.*]], i32 [[LEN:%.*]]) {
7-
; CHECK-NEXT: [[I_INCR:%.*]] = add nuw nsw i32 [[I]], 1
8-
; CHECK-NEXT: [[I_GT_LEN:%.*]] = icmp samesign ugt i32 [[I]], [[LEN]]
9-
; CHECK-NEXT: [[I_INCR_SGT_LEN:%.*]] = icmp sgt i32 [[I_INCR]], [[LEN]]
10-
; CHECK-NEXT: [[RES:%.*]] = icmp sle i1 [[I_INCR_SGT_LEN]], [[I_GT_LEN]]
11-
; CHECK-NEXT: ret i1 [[RES]]
7+
; CHECK-NEXT: ret i1 true
128
;
139
%i.incr = add nsw nuw i32 %i, 1
1410
%i.gt.len = icmp samesign ugt i32 %i, %len
@@ -20,11 +16,7 @@ define i1 @incr_sle(i32 %i, i32 %len) {
2016
define i1 @incr_sge(i32 %i, i32 %len) {
2117
; CHECK-LABEL: define i1 @incr_sge(
2218
; CHECK-SAME: i32 [[I:%.*]], i32 [[LEN:%.*]]) {
23-
; CHECK-NEXT: [[I_INCR:%.*]] = add nuw nsw i32 [[I]], 1
24-
; CHECK-NEXT: [[I_LT_LEN:%.*]] = icmp samesign ult i32 [[I]], [[LEN]]
25-
; CHECK-NEXT: [[I_INCR_SLT_LEN:%.*]] = icmp slt i32 [[I_INCR]], [[LEN]]
26-
; CHECK-NEXT: [[RES:%.*]] = icmp sge i1 [[I_INCR_SLT_LEN]], [[I_LT_LEN]]
27-
; CHECK-NEXT: ret i1 [[RES]]
19+
; CHECK-NEXT: ret i1 true
2820
;
2921
%i.incr = add nsw nuw i32 %i, 1
3022
%i.lt.len = icmp samesign ult i32 %i, %len
@@ -36,11 +28,7 @@ define i1 @incr_sge(i32 %i, i32 %len) {
3628
define i1 @incr_ule(i32 %i, i32 %len) {
3729
; CHECK-LABEL: define i1 @incr_ule(
3830
; CHECK-SAME: i32 [[I:%.*]], i32 [[LEN:%.*]]) {
39-
; CHECK-NEXT: [[I_INCR:%.*]] = add nuw nsw i32 [[I]], 1
40-
; CHECK-NEXT: [[I_GT_LEN:%.*]] = icmp samesign ugt i32 [[I]], [[LEN]]
41-
; CHECK-NEXT: [[I_INCR_SGT_LEN:%.*]] = icmp sgt i32 [[I_INCR]], [[LEN]]
42-
; CHECK-NEXT: [[RES:%.*]] = icmp ule i1 [[I_GT_LEN]], [[I_INCR_SGT_LEN]]
43-
; CHECK-NEXT: ret i1 [[RES]]
31+
; CHECK-NEXT: ret i1 true
4432
;
4533
%i.incr = add nsw nuw i32 %i, 1
4634
%i.gt.len = icmp samesign ugt i32 %i, %len
@@ -52,11 +40,7 @@ define i1 @incr_ule(i32 %i, i32 %len) {
5240
define i1 @incr_uge(i32 %i, i32 %len) {
5341
; CHECK-LABEL: define i1 @incr_uge(
5442
; CHECK-SAME: i32 [[I:%.*]], i32 [[LEN:%.*]]) {
55-
; CHECK-NEXT: [[I_INCR:%.*]] = add nuw nsw i32 [[I]], 1
56-
; CHECK-NEXT: [[I_LT_LEN:%.*]] = icmp samesign ult i32 [[I]], [[LEN]]
57-
; CHECK-NEXT: [[I_INCR_SLT_LEN:%.*]] = icmp slt i32 [[I_INCR]], [[LEN]]
58-
; CHECK-NEXT: [[RES:%.*]] = icmp uge i1 [[I_LT_LEN]], [[I_INCR_SLT_LEN]]
59-
; CHECK-NEXT: ret i1 [[RES]]
43+
; CHECK-NEXT: ret i1 true
6044
;
6145
%i.incr = add nsw nuw i32 %i, 1
6246
%i.lt.len = icmp samesign ult i32 %i, %len

0 commit comments

Comments
 (0)